blob: 7a177be34dc703019db724a0f90215060e5136e8 [file] [log] [blame]
Index: lucene/misc/src/test/org/apache/lucene/search/TestNativeSearch.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/search/TestNativeSearch.java (revision 0)
+++ lucene/misc/src/test/org/apache/lucene/search/TestNativeSearch.java (working copy)
@@ -0,0 +1,193 @@
+package org.apache.lucene.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.TextField;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.MMapDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util._TestUtil;
+
+public class TestNativeSearch extends LuceneTestCase {
+
+ public void testBasic() throws Exception {
+ File tmpDir = _TestUtil.getTempDir("nativesearch");
+ Directory dir = new MMapDirectory(tmpDir);
+ IndexWriterConfig iwc = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
+ iwc.setCodec(Codec.forName("Lucene42"));
+ IndexWriter w = new IndexWriter(dir, iwc);
+ Document doc = new Document();
+ doc.add(new TextField("field", "a b c", Field.Store.NO));
+ w.addDocument(doc);
+ doc = new Document();
+ doc.add(new TextField("field", "a b x", Field.Store.NO));
+ w.addDocument(doc);
+ doc = new Document();
+ doc.add(new TextField("field", "x", Field.Store.NO));
+ w.addDocument(doc);
+ IndexReader r = DirectoryReader.open(w, true);
+ w.close();
+ IndexSearcher s = new IndexSearcher(r);
+
+ BooleanQuery bq = new BooleanQuery();
+ bq.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "c")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "x")), BooleanClause.Occur.SHOULD);
+
+ assertSameHits(s, bq);
+
+ // no matches:
+ bq = new BooleanQuery();
+ bq.add(new TermQuery(new Term("field", "p")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "p")), BooleanClause.Occur.SHOULD);
+ assertSameHits(s, bq);
+
+ r.close();
+ dir.close();
+ }
+
+ public void testBasic2() throws Exception {
+ File tmpDir = _TestUtil.getTempDir("nativesearch");
+ Directory dir = new MMapDirectory(tmpDir);
+ IndexWriterConfig iwc = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
+ iwc.setCodec(Codec.forName("Lucene42"));
+ IndexWriter w = new IndexWriter(dir, iwc);
+ int numDocs = 140;
+ for(int i=0;i<numDocs;i++) {
+ Document doc = new Document();
+ doc.add(new TextField("field", "a b c", Field.Store.NO));
+ w.addDocument(doc);
+ }
+
+ IndexReader r = DirectoryReader.open(w, true);
+ w.close();
+
+ IndexSearcher s = new IndexSearcher(r);
+
+ BooleanQuery bq = new BooleanQuery();
+ bq.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "c")), BooleanClause.Occur.SHOULD);
+
+ assertSameHits(s, bq);
+
+ r.close();
+ dir.close();
+ }
+
+ // nocommit test w/ deletions
+
+ public void testBasic3() throws Exception {
+ File tmpDir = _TestUtil.getTempDir("nativesearch");
+ Directory dir = new MMapDirectory(tmpDir);
+ IndexWriterConfig iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
+ iwc.setCodec(Codec.forName("Lucene42"));
+ IndexWriter w = new IndexWriter(dir, iwc);
+ int numDocs = atLeast(10000);
+ for(int i=0;i<numDocs;i++) {
+ Document doc = new Document();
+ StringBuilder content = new StringBuilder();
+ content.append(" a");
+ if ((i % 2) == 0) {
+ content.append(" b");
+ }
+ if ((i % 4) == 0) {
+ content.append(" c");
+ }
+ if ((i % 8) == 0) {
+ content.append(" d");
+ }
+ if ((i % 16) == 0) {
+ content.append(" e");
+ }
+ if ((i % 32) == 0) {
+ content.append(" f");
+ }
+ doc.add(new TextField("field", content.toString(), Field.Store.NO));
+ w.addDocument(doc);
+ }
+
+ IndexReader r = DirectoryReader.open(w, true);
+ w.close();
+
+ IndexSearcher s = new IndexSearcher(r);
+
+ BooleanQuery bq = new BooleanQuery();
+ bq.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "b")), BooleanClause.Occur.SHOULD);
+ assertSameHits(s, bq);
+
+ bq = new BooleanQuery();
+ bq.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "c")), BooleanClause.Occur.SHOULD);
+ assertSameHits(s, bq);
+
+ bq = new BooleanQuery();
+ bq.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "d")), BooleanClause.Occur.SHOULD);
+ assertSameHits(s, bq);
+
+ bq = new BooleanQuery();
+ bq.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "e")), BooleanClause.Occur.SHOULD);
+ assertSameHits(s, bq);
+
+ bq = new BooleanQuery();
+ bq.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
+ bq.add(new TermQuery(new Term("field", "f")), BooleanClause.Occur.SHOULD);
+ assertSameHits(s, bq);
+
+ r.close();
+ dir.close();
+ }
+
+
+ private void assertSameHits(IndexSearcher s, Query q) throws IOException {
+ TopDocs expected = s.search(q, 10);
+ TopDocs actual = NativeSearch.search(s, q, 10);
+ assertSameHits(expected, actual);
+
+ int maxDoc = s.getIndexReader().maxDoc();
+ expected = s.search(q, maxDoc);
+ actual = NativeSearch.search(s, q, maxDoc);
+ assertSameHits(expected, actual);
+ }
+
+ private void assertSameHits(TopDocs expected, TopDocs actual) {
+ assertEquals(expected.totalHits, actual.totalHits);
+ assertEquals(expected.getMaxScore(), actual.getMaxScore(), 0.0f);
+ assertEquals(expected.scoreDocs.length, actual.scoreDocs.length);
+ for(int i=0;i<expected.scoreDocs.length;i++) {
+ assertEquals("hit " + i, expected.scoreDocs[i].doc, actual.scoreDocs[i].doc);
+ // nocommit why not exactly the same?
+ //assertEquals("hit " + i, expected.scoreDocs[i].score, actual.scoreDocs[i].score, 0.0f);
+ assertEquals("hit " + i, expected.scoreDocs[i].score, actual.scoreDocs[i].score, 0.00001f);
+ }
+ }
+}
Property changes on: lucene/misc/src/test/org/apache/lucene/search/TestNativeSearch.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/misc/src/java/org/apache/lucene/search/gen_Packed.py
===================================================================
--- lucene/misc/src/java/org/apache/lucene/search/gen_Packed.py (revision 0)
+++ lucene/misc/src/java/org/apache/lucene/search/gen_Packed.py (working copy)
@@ -0,0 +1,182 @@
+#! /usr/bin/env python
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+import StringIO
+
+"""Code generation for bulk operations"""
+
+MAX_SPECIALIZED_BITS_PER_VALUE = 24;
+PACKED_64_SINGLE_BLOCK_BPV = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16, 21, 32]
+OUTPUT_FILE = "src/java/org/apache/lucene/search/NativeSearch.cpp"
+
+def is_power_of_two(n):
+ return n & (n - 1) == 0
+
+def casts(typ):
+ cast_start = "(%s) (" %typ
+ cast_end = ")"
+ return cast_start, cast_end
+
+def hexNoLSuffix(n):
+ # On 32 bit Python values > (1 << 31)-1 will have L appended by hex function:
+ s = hex(n)
+ if s.endswith('L'):
+ s = s[:-1]
+ return s
+
+def masks(bits):
+ if bits == 64:
+ return "", ""
+ return "(", " & %sL)" %(hexNoLSuffix((1 << bits) - 1))
+
+def get_type(bits):
+ if bits == 8:
+ return "byte"
+ elif bits == 16:
+ return "short"
+ elif bits == 32:
+ return "int"
+ elif bits == 64:
+ return "long"
+ else:
+ assert False
+
+def block_value_count(bpv, bits=64):
+ blocks = bpv
+ values = blocks * bits / bpv
+ iters = 2
+ while blocks % 2 == 0 and values % 2 == 0:
+ blocks /= 2
+ values /= 2
+ iters *= 2
+ assert values * bpv == bits * blocks, "%d values, %d blocks, %d bits per value" %(values, blocks, bpv)
+ return blocks, values, iters
+
+def p64_decode(bpv, f):
+ mask = (1 << bpv) - 1
+
+ blocks, values, iters = block_value_count(bpv)
+ cast_start, cast_end = casts('int')
+
+ f.write("static void decode%d(unsigned long *blocks, unsigned int *values) {\n" % bpv)
+ f.write(" int blocksOffset = 0;\n")
+ f.write(" int valuesOffset = 0;\n")
+ #f.write(' printf("decode %s\\n");\n' % bpv);
+ f.write(" for (int i = 0; i < %d; ++i) {\n" % iters)
+
+ if is_power_of_two(bpv):
+ f.write(" unsigned long block = blocks[blocksOffset++];\n")
+ f.write(" block = __bswap_64(block);\n")
+ f.write(" for (int shift = %d; shift >= 0; shift -= %d) {\n" %(64 - bpv, bpv))
+ f.write(" values[valuesOffset++] = %s(block >> shift) & %d%s;\n" %(cast_start, mask, cast_end))
+ f.write(" }\n")
+ else:
+ for i in xrange(0, values):
+ block_offset = i * bpv / 64
+ bit_offset = (i * bpv) % 64
+ if bit_offset == 0:
+ # start of block
+ f.write(" unsigned long block%d = blocks[blocksOffset++];\n" %block_offset);
+ f.write(" block%d = __bswap_64(block%d);\n" % (block_offset, block_offset))
+ f.write(" values[valuesOffset++] = %sblock%d >> %d%s;\n" %(cast_start, block_offset, 64 - bpv, cast_end))
+ elif bit_offset + bpv == 64:
+ # end of block
+ f.write(" values[valuesOffset++] = %sblock%d & %dL%s;\n" %(cast_start, block_offset, mask, cast_end))
+ elif bit_offset + bpv < 64:
+ # middle of block
+ f.write(" values[valuesOffset++] = %s(block%d >> %d) & %dL%s;\n" %(cast_start, block_offset, 64 - bit_offset - bpv, mask, cast_end))
+ else:
+ # value spans across 2 blocks
+ mask1 = (1 << (64 - bit_offset)) -1
+ shift1 = bit_offset + bpv - 64
+ shift2 = 64 - shift1
+ f.write(" unsigned long block%d = blocks[blocksOffset++];\n" %(block_offset + 1));
+ f.write(" block%d = __bswap_64(block%d);\n" % (block_offset+1, block_offset+1))
+ f.write(" values[valuesOffset++] = %s((block%d & %dL) << %d) | (block%d >> %d)%s;\n" %(cast_start, block_offset, mask1, shift1, block_offset + 1, shift2, cast_end))
+ f.write(" }\n")
+ f.write("}\n")
+
+
+if __name__ == '__main__':
+ f = StringIO.StringIO()
+ f.write('// BEGIN AUTOGEN CODE (gen_Packed.py)\n')
+
+ for bpv in xrange(1, 32):
+ if bpv in (1, 2, 4):
+ # Handled by decodeSingleBlockN
+ continue
+ f.write('\n')
+ p64_decode(bpv, f)
+
+ f.write('''
+
+static void readPackedBlock(unsigned long *longBuffer, PostingsState *sub, unsigned int *dest) {
+ unsigned char bitsPerValue = readByte(sub);
+ //printf("\\nreadPackedBlock bpv=%d\\n", bitsPerValue);
+ if (bitsPerValue == 0) {
+ // All values equal
+ unsigned int v = readVInt(sub);
+ for(int i=0;i<BLOCK_SIZE;i++) {
+ dest[i] = v;
+ }
+ } else {
+ int numBytes = bitsPerValue*16;
+ //printf("\\n %d bytes @ p=%d\\n", numBytes, (int) (sub->p - globalAddress));
+ // Align to 8 bytes:
+ long x = (long) sub->p;
+ x = (x+7) & ~7;
+ sub->p = (unsigned char *) x;
+
+ //memcpy(longBuffer, sub->p, numBytes);
+ longBuffer = (unsigned long *) sub->p;
+ sub->p += numBytes;
+
+ // NOTE: Block PF uses PACKED_SINGLE_BLOCK for
+ // bpv=1,2,4, else "ordinary" packed:
+ switch(bitsPerValue) {
+''')
+
+ for bpv in xrange(1, 32):
+ f.write(' case %d:\n' % bpv)
+ if bpv in (1,2,4):
+ f.write(' decodeSingleBlock%d(longBuffer, dest);\n' % bpv)
+ else:
+ f.write(' decode%d(longBuffer, dest);\n' % bpv)
+ f.write(' break;\n')
+
+ f.write('''
+ }
+ }
+}
+''')
+
+ f.write('// END AUTOGEN CODE (gen_Packed.py)\n')
+
+ s = f.getvalue()
+
+ s2 = open(OUTPUT_FILE, 'rb').read()
+ i = s2.find('// BEGIN AUTOGEN CODE (gen_Packed.py)\n')
+ if i == -1:
+ raise RuntimeError('cannot find BEGIN AUTOGEN comment')
+ j = s2.find('// END AUTOGEN CODE (gen_Packed.py)\n')
+ if j == -1:
+ raise RuntimeError('cannot find END AUTOGEN comment')
+
+ s2 = s2[:i] + s + s2[j+36:]
+
+ open(OUTPUT_FILE, 'wb').write(s2)
+
Property changes on: lucene/misc/src/java/org/apache/lucene/search/gen_Packed.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/misc/src/java/org/apache/lucene/search/NativeSearch.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/search/NativeSearch.java (revision 0)
+++ lucene/misc/src/java/org/apache/lucene/search/NativeSearch.java (working copy)
@@ -0,0 +1,532 @@
+package org.apache.lucene.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.reflect.*;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.LiveDocsFormat;
+import org.apache.lucene.codecs.NormsFormat;
+import org.apache.lucene.codecs.PostingsFormat;
+import org.apache.lucene.codecs.lucene40.Lucene40LiveDocsFormat;
+import org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat;
+import org.apache.lucene.codecs.lucene42.Lucene42NormsFormat;
+import org.apache.lucene.codecs.perfield.PerFieldPostingsFormat;
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.SegmentReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.similarities.DefaultSimilarity;
+import org.apache.lucene.search.similarities.Similarity;
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.NativeMMapDirectory;
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.InPlaceMergeSorter;
+
+/** Uses JNI (C) code to execute a BooleanQuery. Note that this
+ * class can currently only run in a very precise
+ * situation: searcher's leaves are all normal
+ * SegmentReaders, default postings format, collecting top
+ * scoring hits, only OR of TermQuery, using NativeMMapDirectory
+ * and default similarity. */
+
+public class NativeSearch {
+
+ static {
+ System.loadLibrary("NativeSearch");
+ }
+
+ final IndexSearcher searcher;
+
+ public NativeSearch(IndexSearcher searcher) {
+ this.searcher = searcher;
+ }
+
+ private static native int searchSegment(
+ // PQ holding top hits so far, pre-filled with sentinel
+ // values:
+ int[] topDocIDs,
+ float[] topScores,
+
+ // Current segment's maxDoc
+ int maxDoc,
+
+ // Current segment's docBase
+ int docBase,
+
+ // Current segment's liveDocs, or null:
+ byte[] liveDocBytes,
+
+ // weightValue from each TermWeight:
+ float[] termWeights,
+
+ // Norms for the field (all TermQuery must be against a single field):
+ byte[] norms,
+
+ // nocommit silly to pass this once for each segment:
+ // Cache, mapping byte norm -> float
+ float[] normTable,
+
+ // Coord factors from BQ:
+ float[] coordFactors,
+
+ // If the term has only one docID in this segment (it was "pulsed") then its set here, else -1:
+ int[] singletonDocIDs,
+
+ // docFreq of each term
+ int[] docFreqs,
+
+ // Offset in the .doc file where this term's docs+freqs begin:
+ long[] docTermStartFPs,
+
+ // Address in memory where .doc file is mapped:
+ long docFileAddress);
+
+ public static TopDocs search(IndexSearcher searcher, Query query, int topN) throws IOException {
+
+ query = searcher.rewrite(query);
+ //System.out.println("after rewrite: " + query);
+
+ try {
+ return _search(searcher, query, topN);
+ } catch (IllegalArgumentException iae) {
+ return searcher.search(query, topN);
+ }
+ }
+
+ private static TopDocs _search(IndexSearcher searcher, Query query, int topN) throws IOException {
+
+ if (topN == 0) {
+ throw new IllegalArgumentException("topN must be > 0; got: 0");
+ }
+
+ if (topN > searcher.getIndexReader().maxDoc()) {
+ topN = searcher.getIndexReader().maxDoc();
+ }
+
+ List<AtomicReaderContext> leaves = searcher.getIndexReader().leaves();
+ Similarity sim = searcher.getSimilarity();
+
+ if (!(sim instanceof DefaultSimilarity)) {
+ throw new IllegalArgumentException("searcher.getSimilarity() must be DefaultSimilarity; got: " + sim);
+ }
+
+ if (!(query instanceof BooleanQuery)) {
+ throw new IllegalArgumentException("rewritten query must be BooleanQuery; got: " + query);
+ }
+
+ BooleanQuery bq = (BooleanQuery) query;
+
+ if (bq.getMinimumNumberShouldMatch() > 1) {
+ throw new IllegalArgumentException("can only handle minimumNumberShouldMatch==0; got: " + bq.getMinimumNumberShouldMatch());
+ }
+
+ boolean coordDisabled = bq.isCoordDisabled();
+
+ BooleanClause[] clauses = bq.getClauses();
+ if (clauses.length == 0) {
+ throw new IllegalArgumentException("query must have at least one BooleanClause; got: none");
+ }
+
+ String field = null;
+ String[] terms = new String[clauses.length];
+ for(int i=0;i<clauses.length;i++) {
+ BooleanClause clause = clauses[i];
+ if (clause.getOccur() != BooleanClause.Occur.SHOULD) {
+ throw new IllegalArgumentException("only Occur.SHOULD supported; got: " + clause.getOccur());
+ }
+ if (!(clause.getQuery() instanceof TermQuery)) {
+ throw new IllegalArgumentException("sub-queries must be TermQuery; got: " + clause.getQuery());
+ }
+ TermQuery tq = (TermQuery) clause.getQuery();
+ Term term = tq.getTerm();
+ if (i == 0) {
+ field = term.field();
+ } else if (!field.equals(term.field())) {
+ throw new IllegalArgumentException("all sub-queries must be TermQuery against the same field; got both field=" + field + " and field=" + term.field());
+ }
+ terms[i] = term.text();
+ }
+
+ Weight w = searcher.createNormalizedWeight(query);
+
+ List<Weight> subWeights = getBooleanSubWeights(w);
+
+ float[] topScores = new float[topN+1];
+ Arrays.fill(topScores, Float.MIN_VALUE);
+ int[] topDocIDs = new int[topN+1];
+ Arrays.fill(topDocIDs, Integer.MAX_VALUE);
+ int totalHits = 0;
+
+ for(int readerIDX=0;readerIDX<leaves.size();readerIDX++) {
+ AtomicReaderContext ctx = leaves.get(readerIDX);
+ if (!(ctx.reader() instanceof SegmentReader)) {
+ throw new IllegalArgumentException("leaves must be SegmentReaders; got: " + ctx.reader());
+ }
+ SegmentReader reader = (SegmentReader) ctx.reader();
+ if (!(reader.directory() instanceof NativeMMapDirectory)) {
+ throw new IllegalArgumentException("directory must be a NativeMMapDirectory; got: " + reader.directory());
+ }
+ Codec codec = reader.getSegmentInfo().info.getCodec();
+
+ FieldInfo fieldInfo = reader.getFieldInfos().fieldInfo(field);
+ if (fieldInfo.getIndexOptions() == FieldInfo.IndexOptions.DOCS_ONLY) {
+ throw new IllegalArgumentException("field must be indexed with freqs; got: " + fieldInfo.getIndexOptions());
+ }
+
+ LiveDocsFormat ldf = codec.liveDocsFormat();
+ if (!(ldf instanceof Lucene40LiveDocsFormat)) {
+ throw new IllegalArgumentException("LiveDocsFormat must be Lucene40LiveDocsFormat; got: " + ldf);
+ }
+
+ PostingsFormat pf = codec.postingsFormat();
+ if (pf instanceof PerFieldPostingsFormat) {
+ pf = ((PerFieldPostingsFormat) pf).getPostingsFormatForField(field);
+ }
+
+ if (!(pf instanceof Lucene41PostingsFormat)) {
+ throw new IllegalArgumentException("PostingsFormat for field=" + field + " must be Lucene41PostingsFormat; got: " + pf);
+ }
+
+ NormsFormat nf = codec.normsFormat();
+ if (!(nf instanceof Lucene42NormsFormat)) {
+ throw new IllegalArgumentException("NormsFormat for field=" + field + " must be Lucene42NormsFormat; got: " + nf);
+ }
+
+ NumericDocValues norms = reader.getNormValues(field);
+ if (norms == null) {
+ throw new IllegalArgumentException("field=" + field + " must not omit norms; got: no norms");
+ }
+
+ byte[] normBytes = getNormsBytes(norms);
+
+ Bits liveDocs = reader.getLiveDocs();
+
+ byte[] liveDocsBytes;
+ if (liveDocs != null) {
+ liveDocsBytes = getLiveDocsBits(liveDocs);
+ } else {
+ liveDocsBytes = null;
+ }
+
+ List<Scorer> scorers = new ArrayList<Scorer>();
+ for(int i=0;i<terms.length;i++) {
+ Scorer scorer = subWeights.get(i).scorer(ctx, true, false, liveDocs);
+ if (scorer != null) {
+ scorers.add(scorer);
+ }
+ }
+
+ if (!scorers.isEmpty()) {
+
+ float[] coordFactors = new float[scorers.size()+1];
+ for(int i=0;i<coordFactors.length;i++) {
+ float f;
+ if (coordDisabled) {
+ f = 1.0f;
+ } else if (scorers.size() == 1) {
+ f = 1.0f;
+ } else {
+ f = sim.coord(i, scorers.size());
+ }
+ coordFactors[i] = f;
+ }
+
+ float[] normTable = getNormTable();
+ final float[] termWeights = new float[scorers.size()];
+ final int[] singletonDocIDs = new int[scorers.size()];
+ final int[] docFreqs = new int[scorers.size()];
+ final long[] docTermStartFPs = new long[scorers.size()];
+ long address = 0;
+ for(int i=0;i<scorers.size();i++) {
+ Scorer scorer = scorers.get(i);
+ termWeights[i] = getTermWeight(scorer);
+ DocsEnum docsEnum = getDocsEnum(scorer);
+ docFreqs[i] = getDocFreq(docsEnum);
+ docTermStartFPs[i] = getDocTermStartFP(docsEnum);
+
+ if (docFreqs[i] > 1) {
+ IndexInput docIn = getDocIn(docsEnum);
+ if (address == 0) {
+ address = getMMapAddress(docIn);
+ }
+ singletonDocIDs[i] = -1;
+ } else {
+ // Pulsed
+ singletonDocIDs[i] = getSingletonDocID(docsEnum);
+ assert singletonDocIDs[i] >= 0;
+ }
+ }
+
+ // Sort by descending docFreq: we do this because
+ // the first scorer is handled separately (saves an
+ // if inside the inner loop):
+ new InPlaceMergeSorter() {
+ @Override
+ protected int compare(int i, int j) {
+ return docFreqs[j] - docFreqs[i];
+ }
+
+ @Override
+ protected void swap(int i, int j) {
+ int x = docFreqs[i];
+ docFreqs[i] = docFreqs[j];
+ docFreqs[j] = x;
+
+ x = singletonDocIDs[i];
+ singletonDocIDs[i] = singletonDocIDs[j];
+ singletonDocIDs[j] = x;
+
+ long y = docTermStartFPs[i];
+ docTermStartFPs[i] = docTermStartFPs[j];
+ docTermStartFPs[j] = y;
+
+ float z = termWeights[i];
+ termWeights[i] = termWeights[j];
+ termWeights[j] = z;
+ }
+ }.sort(0, scorers.size()-1);
+
+ totalHits += searchSegment(topDocIDs,
+ topScores,
+ reader.maxDoc(),
+ ctx.docBase,
+ liveDocsBytes,
+ termWeights,
+ normBytes,
+ normTable,
+ coordFactors,
+ singletonDocIDs,
+ docFreqs,
+ docTermStartFPs,
+ address);
+ }
+ }
+
+ //System.out.println("totalHits=" + totalHits);
+
+ ScoreDoc[] scoreDocs = new ScoreDoc[Math.min(totalHits, topN)];
+
+ int heapSize = topN;
+
+ for(int i=0;i<topN-scoreDocs.length;i++) {
+ topScores[1] = topScores[heapSize];
+ topDocIDs[1] = topDocIDs[heapSize];
+ heapSize--;
+ downHeap(heapSize, topDocIDs, topScores);
+ }
+
+ for(int i=scoreDocs.length-1;i>=0;i--) {
+ scoreDocs[i] = new ScoreDoc(topDocIDs[1], topScores[1]);
+ topScores[1] = topScores[heapSize];
+ topDocIDs[1] = topDocIDs[heapSize];
+ //System.out.println(" topDocs[" + i + "]=" + scoreDocs[i].doc);
+ heapSize--;
+ downHeap(heapSize, topDocIDs, topScores);
+ }
+
+ float maxScore;
+ if (scoreDocs.length > 0) {
+ maxScore = scoreDocs[0].score;
+ } else {
+ maxScore = Float.NaN;
+ }
+
+ return new TopDocs(totalHits, scoreDocs, maxScore);
+ }
+
+ private static boolean lessThan(int docID1, float score1, int docID2, float score2) {
+ if (score1 < score2) {
+ return true;
+ } else if (score1 > score2) {
+ return false;
+ } else {
+ if (docID1 > docID2) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ private static void downHeap(int heapSize, int[] topDocIDs, float[] topScores) {
+ int i = 1;
+ // save top node
+ int savDocID = topDocIDs[i];
+ float savScore = topScores[i];
+ int j = i << 1; // find smaller child
+ int k = j + 1;
+ if (k <= heapSize && lessThan(topDocIDs[k], topScores[k], topDocIDs[j], topScores[j])) {
+ j = k;
+ }
+ while (j <= heapSize && lessThan(topDocIDs[j], topScores[j], savDocID, savScore)) {
+ // shift up child
+ topDocIDs[i] = topDocIDs[j];
+ topScores[i] = topScores[j];
+ i = j;
+ j = i << 1;
+ k = j + 1;
+ if (k <= heapSize && lessThan(topDocIDs[k], topScores[k], topDocIDs[j], topScores[j])) {
+ j = k;
+ }
+ }
+ // install saved node
+ topDocIDs[i] = savDocID;
+ topScores[i] = savScore;
+ }
+
+ // nocommit we can move most of the reflection lookups to
+ // static:
+
+ private static float[] getNormTable() {
+ try {
+ Class<?> x = Class.forName("org.apache.lucene.search.similarities.TFIDFSimilarity");
+ Field f = x.getDeclaredField("NORM_TABLE");
+ f.setAccessible(true);
+ return (float[]) f.get(x);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access NORM_TABLE", e);
+ }
+ }
+
+ private static long getMMapAddress(IndexInput in) {
+ try {
+ Class<?> x = Class.forName("org.apache.lucene.store.NativeMMapDirectory$NativeMMapIndexInput");
+ Field f = x.getDeclaredField("address");
+ f.setAccessible(true);
+ return f.getLong(in);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access ByteBuffer addresses via reflection", e);
+ }
+ }
+
+ private static float getTermWeight(Scorer scorer) {
+ try {
+ Class<?> x = Class.forName("org.apache.lucene.search.TermScorer");
+ Field f = x.getDeclaredField("docScorer");
+ f.setAccessible(true);
+ Object o = f.get(scorer);
+ Class<?> y = Class.forName("org.apache.lucene.search.similarities.TFIDFSimilarity$ExactTFIDFDocScorer");
+ Field weightsField = y.getDeclaredField("weightValue");
+ weightsField.setAccessible(true);
+ return weightsField.getFloat(o);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access TFIDFSimilarity via reflection", e);
+ }
+ }
+
+ private static byte[] getLiveDocsBits(Bits bits) {
+ try {
+ Class<?> x = Class.forName("org.apache.lucene.codecs.lucene40.BitVector");
+ Field f = x.getDeclaredField("bits");
+ f.setAccessible(true);
+ return (byte[]) f.get(bits);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access TermScorer.docsEnum via reflection", e);
+ }
+ }
+
+ private static DocsEnum getDocsEnum(Scorer scorer) {
+ try {
+ Class<?> x = Class.forName("org.apache.lucene.search.TermScorer");
+ Field f = x.getDeclaredField("docsEnum");
+ f.setAccessible(true);
+ return (DocsEnum) f.get(scorer);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access TermScorer.docsEnum via reflection", e);
+ }
+ }
+
+ private static int getDocFreq(DocsEnum docsEnum) {
+ try {
+ Class<?> x = Class.forName("org.apache.lucene.codecs.lucene41.Lucene41PostingsReader$BlockDocsEnum");
+ Field f = x.getDeclaredField("docFreq");
+ f.setAccessible(true);
+ return f.getInt(docsEnum);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access docFreq via reflection", e);
+ }
+ }
+
+ private static IndexInput getDocIn(DocsEnum docsEnum) {
+ try {
+ final Class<?> x = Class.forName("org.apache.lucene.codecs.lucene41.Lucene41PostingsReader$BlockDocsEnum");
+ final Field f = x.getDeclaredField("startDocIn");
+ f.setAccessible(true);
+ return (IndexInput) f.get(docsEnum);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access docFreq via reflection", e);
+ }
+ }
+
+ private static long getDocTermStartFP(DocsEnum docsEnum) {
+ try {
+ final Class<?> x = Class.forName("org.apache.lucene.codecs.lucene41.Lucene41PostingsReader$BlockDocsEnum");
+ final Field f = x.getDeclaredField("docTermStartFP");
+ f.setAccessible(true);
+ return f.getLong(docsEnum);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access docFreq via reflection", e);
+ }
+ }
+
+ private static int getSingletonDocID(DocsEnum docsEnum) {
+ try {
+ final Class<?> x = Class.forName("org.apache.lucene.codecs.lucene41.Lucene41PostingsReader$BlockDocsEnum");
+ final Field f = x.getDeclaredField("singletonDocID");
+ f.setAccessible(true);
+ return f.getInt(docsEnum);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access docFreq via reflection", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static List<Weight> getBooleanSubWeights(Weight w) {
+ try {
+ final Class<?> x = Class.forName("org.apache.lucene.search.BooleanQuery$BooleanWeight");
+ final Field weightsField = x.getDeclaredField("weights");
+ weightsField.setAccessible(true);
+ return (List<Weight>) weightsField.get(w);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access BooleanWeight.weights via reflection", e);
+ }
+ }
+
+ private static byte[] getNormsBytes(NumericDocValues norms) {
+ try {
+ final Class<?> x = Class.forName("org.apache.lucene.codecs.lucene42.Lucene42DocValuesProducer$3");
+ final Field bytesField = x.getDeclaredField("val$bytes");
+ bytesField.setAccessible(true);
+ return (byte[]) bytesField.get(norms);
+ } catch (Exception e) {
+ throw new IllegalStateException("failed to access norm byte[] via reflection", e);
+ }
+ }
+}
Property changes on: lucene/misc/src/java/org/apache/lucene/search/NativeSearch.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/misc/src/java/org/apache/lucene/search/NativeSearch.cpp
===================================================================
--- lucene/misc/src/java/org/apache/lucene/search/NativeSearch.cpp (revision 0)
+++ lucene/misc/src/java/org/apache/lucene/search/NativeSearch.cpp (working copy)
@@ -0,0 +1,2840 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+//
+// To see assembly:
+//
+// g++ -fpermissive -S -O4 -o test.s -I/usr/local/src/jdk1.6.0_32/include -I/usr/local/src/jdk1.6.0_32/include/linux /l/nativebq/lucene/misc/src/java/org/apache/lucene/search/NativeSearch.cpp
+//
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <jni.h>
+#include <math.h> // for sqrt
+#include <stdlib.h> // malloc
+#include <string.h> // memcpy
+#include <byteswap.h>
+
+#define BLOCK_SIZE 128
+#define NO_MORE_DOCS 2147483647
+
+#define CHUNK 2048
+#define MASK (CHUNK-1)
+
+typedef struct {
+ // How many docs left
+ int docsLeft;
+
+ // Where (mapped in RAM) we decode postings from:
+ unsigned char* p;
+
+ // Current block
+ unsigned int *docDeltas;
+ unsigned int *freqs;
+ int nextDocID;
+ int blockLastRead;
+ int blockEnd;
+ int id;
+} PostingsState;
+
+typedef struct {
+ int docID;
+ double score;
+ int coord;
+} Bucket;
+
+bool isSet(unsigned char *bits, int docID) {
+ return (bits[docID >> 3] & (1 << (docID & 7))) != 0;
+}
+
+static unsigned char readByte(PostingsState *sub) {
+ //printf("readByte p=%ld\n", sub->p);fflush(stdout);
+ return *(sub->p++);
+}
+
+static unsigned int readVInt(PostingsState *sub) {
+ char b = (char) readByte(sub);
+ if (b >= 0) return b;
+ unsigned int i = b & 0x7F;
+ b = readByte(sub);
+ i |= (b & 0x7F) << 7;
+ if (b >= 0) return i;
+ b = readByte(sub);
+ i |= (b & 0x7F) << 14;
+ if (b >= 0) return i;
+ b = readByte(sub);
+ i |= (b & 0x7F) << 21;
+ if (b >= 0) return i;
+ b = readByte(sub);
+ // Warning: the next ands use 0x0F / 0xF0 - beware copy/paste errors:
+ return i | ((b & 0x0F) << 28);
+}
+
+static void decodeSingleBlock1(unsigned long *blocks, unsigned int *values) {
+ int valuesOffset = 0;
+ long mask = 1;
+ for(int i=0;i<2;i++) {
+ unsigned long block = blocks[i];
+ block = __bswap_64(block);
+ values[valuesOffset++] = (int) (block & mask);
+ for (int j = 1; j < 64; ++j) {
+ block >>= 1;
+ values[valuesOffset++] = (int) (block & mask);
+ }
+ }
+}
+
+static void decodeSingleBlock2(unsigned long *blocks, unsigned int *values) {
+ int valuesOffset = 0;
+ long mask = 3;
+ for(int i=0;i<4;i++) {
+ unsigned long block = blocks[i];
+ block = __bswap_64(block);
+ values[valuesOffset++] = (int) (block & mask);
+ for (int j = 1; j < 32; ++j) {
+ block >>= 2;
+ values[valuesOffset++] = (int) (block & mask);
+ }
+ }
+}
+
+static void decodeSingleBlock4(unsigned long *blocks, unsigned int *values) {
+ int valuesOffset = 0;
+ long mask = 15;
+ for(int i=0;i<8;i++) {
+ unsigned long block = blocks[i];
+ block = __bswap_64(block);
+ values[valuesOffset++] = (int) (block & mask);
+ for (int j = 1; j < 16; ++j) {
+ block >>= 4;
+ values[valuesOffset++] = (int) (block & mask);
+ }
+ }
+}
+
+// BEGIN AUTOGEN CODE (gen_Packed.py)
+
+static void decode3(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 61);
+ values[valuesOffset++] = (int) ((block0 >> 58) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 55) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 52) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 49) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 46) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 43) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 40) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 37) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 34) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 31) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 28) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 25) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 22) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 19) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 16) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 13) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 10) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 7) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 4) & 7L);
+ values[valuesOffset++] = (int) ((block0 >> 1) & 7L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 1L) << 2) | (block1 >> 62));
+ values[valuesOffset++] = (int) ((block1 >> 59) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 56) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 53) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 50) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 47) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 44) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 41) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 38) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 35) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 32) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 29) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 26) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 23) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 20) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 17) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 14) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 11) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 8) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 5) & 7L);
+ values[valuesOffset++] = (int) ((block1 >> 2) & 7L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 3L) << 1) | (block2 >> 63));
+ values[valuesOffset++] = (int) ((block2 >> 60) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 57) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 54) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 51) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 48) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 45) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 42) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 39) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 36) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 33) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 30) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 27) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 24) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 21) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 18) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 15) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 9) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 6) & 7L);
+ values[valuesOffset++] = (int) ((block2 >> 3) & 7L);
+ values[valuesOffset++] = (int) (block2 & 7L);
+ }
+}
+
+static void decode5(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 59);
+ values[valuesOffset++] = (int) ((block0 >> 54) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 49) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 44) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 39) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 34) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 29) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 24) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 19) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 14) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 9) & 31L);
+ values[valuesOffset++] = (int) ((block0 >> 4) & 31L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 15L) << 1) | (block1 >> 63));
+ values[valuesOffset++] = (int) ((block1 >> 58) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 53) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 48) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 43) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 38) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 33) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 28) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 23) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 18) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 13) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 8) & 31L);
+ values[valuesOffset++] = (int) ((block1 >> 3) & 31L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 7L) << 2) | (block2 >> 62));
+ values[valuesOffset++] = (int) ((block2 >> 57) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 52) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 47) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 42) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 37) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 32) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 27) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 22) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 17) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 7) & 31L);
+ values[valuesOffset++] = (int) ((block2 >> 2) & 31L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 3L) << 3) | (block3 >> 61));
+ values[valuesOffset++] = (int) ((block3 >> 56) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 51) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 46) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 41) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 36) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 31) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 26) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 21) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 16) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 11) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 6) & 31L);
+ values[valuesOffset++] = (int) ((block3 >> 1) & 31L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 1L) << 4) | (block4 >> 60));
+ values[valuesOffset++] = (int) ((block4 >> 55) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 50) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 45) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 40) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 35) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 30) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 25) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 20) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 15) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 10) & 31L);
+ values[valuesOffset++] = (int) ((block4 >> 5) & 31L);
+ values[valuesOffset++] = (int) (block4 & 31L);
+ }
+}
+
+static void decode6(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 4; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 58);
+ values[valuesOffset++] = (int) ((block0 >> 52) & 63L);
+ values[valuesOffset++] = (int) ((block0 >> 46) & 63L);
+ values[valuesOffset++] = (int) ((block0 >> 40) & 63L);
+ values[valuesOffset++] = (int) ((block0 >> 34) & 63L);
+ values[valuesOffset++] = (int) ((block0 >> 28) & 63L);
+ values[valuesOffset++] = (int) ((block0 >> 22) & 63L);
+ values[valuesOffset++] = (int) ((block0 >> 16) & 63L);
+ values[valuesOffset++] = (int) ((block0 >> 10) & 63L);
+ values[valuesOffset++] = (int) ((block0 >> 4) & 63L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 15L) << 2) | (block1 >> 62));
+ values[valuesOffset++] = (int) ((block1 >> 56) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 50) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 44) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 38) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 32) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 26) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 20) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 14) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 8) & 63L);
+ values[valuesOffset++] = (int) ((block1 >> 2) & 63L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 3L) << 4) | (block2 >> 60));
+ values[valuesOffset++] = (int) ((block2 >> 54) & 63L);
+ values[valuesOffset++] = (int) ((block2 >> 48) & 63L);
+ values[valuesOffset++] = (int) ((block2 >> 42) & 63L);
+ values[valuesOffset++] = (int) ((block2 >> 36) & 63L);
+ values[valuesOffset++] = (int) ((block2 >> 30) & 63L);
+ values[valuesOffset++] = (int) ((block2 >> 24) & 63L);
+ values[valuesOffset++] = (int) ((block2 >> 18) & 63L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 63L);
+ values[valuesOffset++] = (int) ((block2 >> 6) & 63L);
+ values[valuesOffset++] = (int) (block2 & 63L);
+ }
+}
+
+static void decode7(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 57);
+ values[valuesOffset++] = (int) ((block0 >> 50) & 127L);
+ values[valuesOffset++] = (int) ((block0 >> 43) & 127L);
+ values[valuesOffset++] = (int) ((block0 >> 36) & 127L);
+ values[valuesOffset++] = (int) ((block0 >> 29) & 127L);
+ values[valuesOffset++] = (int) ((block0 >> 22) & 127L);
+ values[valuesOffset++] = (int) ((block0 >> 15) & 127L);
+ values[valuesOffset++] = (int) ((block0 >> 8) & 127L);
+ values[valuesOffset++] = (int) ((block0 >> 1) & 127L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 1L) << 6) | (block1 >> 58));
+ values[valuesOffset++] = (int) ((block1 >> 51) & 127L);
+ values[valuesOffset++] = (int) ((block1 >> 44) & 127L);
+ values[valuesOffset++] = (int) ((block1 >> 37) & 127L);
+ values[valuesOffset++] = (int) ((block1 >> 30) & 127L);
+ values[valuesOffset++] = (int) ((block1 >> 23) & 127L);
+ values[valuesOffset++] = (int) ((block1 >> 16) & 127L);
+ values[valuesOffset++] = (int) ((block1 >> 9) & 127L);
+ values[valuesOffset++] = (int) ((block1 >> 2) & 127L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 3L) << 5) | (block2 >> 59));
+ values[valuesOffset++] = (int) ((block2 >> 52) & 127L);
+ values[valuesOffset++] = (int) ((block2 >> 45) & 127L);
+ values[valuesOffset++] = (int) ((block2 >> 38) & 127L);
+ values[valuesOffset++] = (int) ((block2 >> 31) & 127L);
+ values[valuesOffset++] = (int) ((block2 >> 24) & 127L);
+ values[valuesOffset++] = (int) ((block2 >> 17) & 127L);
+ values[valuesOffset++] = (int) ((block2 >> 10) & 127L);
+ values[valuesOffset++] = (int) ((block2 >> 3) & 127L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 7L) << 4) | (block3 >> 60));
+ values[valuesOffset++] = (int) ((block3 >> 53) & 127L);
+ values[valuesOffset++] = (int) ((block3 >> 46) & 127L);
+ values[valuesOffset++] = (int) ((block3 >> 39) & 127L);
+ values[valuesOffset++] = (int) ((block3 >> 32) & 127L);
+ values[valuesOffset++] = (int) ((block3 >> 25) & 127L);
+ values[valuesOffset++] = (int) ((block3 >> 18) & 127L);
+ values[valuesOffset++] = (int) ((block3 >> 11) & 127L);
+ values[valuesOffset++] = (int) ((block3 >> 4) & 127L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 15L) << 3) | (block4 >> 61));
+ values[valuesOffset++] = (int) ((block4 >> 54) & 127L);
+ values[valuesOffset++] = (int) ((block4 >> 47) & 127L);
+ values[valuesOffset++] = (int) ((block4 >> 40) & 127L);
+ values[valuesOffset++] = (int) ((block4 >> 33) & 127L);
+ values[valuesOffset++] = (int) ((block4 >> 26) & 127L);
+ values[valuesOffset++] = (int) ((block4 >> 19) & 127L);
+ values[valuesOffset++] = (int) ((block4 >> 12) & 127L);
+ values[valuesOffset++] = (int) ((block4 >> 5) & 127L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 31L) << 2) | (block5 >> 62));
+ values[valuesOffset++] = (int) ((block5 >> 55) & 127L);
+ values[valuesOffset++] = (int) ((block5 >> 48) & 127L);
+ values[valuesOffset++] = (int) ((block5 >> 41) & 127L);
+ values[valuesOffset++] = (int) ((block5 >> 34) & 127L);
+ values[valuesOffset++] = (int) ((block5 >> 27) & 127L);
+ values[valuesOffset++] = (int) ((block5 >> 20) & 127L);
+ values[valuesOffset++] = (int) ((block5 >> 13) & 127L);
+ values[valuesOffset++] = (int) ((block5 >> 6) & 127L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 63L) << 1) | (block6 >> 63));
+ values[valuesOffset++] = (int) ((block6 >> 56) & 127L);
+ values[valuesOffset++] = (int) ((block6 >> 49) & 127L);
+ values[valuesOffset++] = (int) ((block6 >> 42) & 127L);
+ values[valuesOffset++] = (int) ((block6 >> 35) & 127L);
+ values[valuesOffset++] = (int) ((block6 >> 28) & 127L);
+ values[valuesOffset++] = (int) ((block6 >> 21) & 127L);
+ values[valuesOffset++] = (int) ((block6 >> 14) & 127L);
+ values[valuesOffset++] = (int) ((block6 >> 7) & 127L);
+ values[valuesOffset++] = (int) (block6 & 127L);
+ }
+}
+
+static void decode8(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 16; ++i) {
+ unsigned long block = blocks[blocksOffset++];
+ block = __bswap_64(block);
+ for (int shift = 56; shift >= 0; shift -= 8) {
+ values[valuesOffset++] = (int) ((block >> shift) & 255);
+ }
+ }
+}
+
+static void decode9(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 55);
+ values[valuesOffset++] = (int) ((block0 >> 46) & 511L);
+ values[valuesOffset++] = (int) ((block0 >> 37) & 511L);
+ values[valuesOffset++] = (int) ((block0 >> 28) & 511L);
+ values[valuesOffset++] = (int) ((block0 >> 19) & 511L);
+ values[valuesOffset++] = (int) ((block0 >> 10) & 511L);
+ values[valuesOffset++] = (int) ((block0 >> 1) & 511L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 1L) << 8) | (block1 >> 56));
+ values[valuesOffset++] = (int) ((block1 >> 47) & 511L);
+ values[valuesOffset++] = (int) ((block1 >> 38) & 511L);
+ values[valuesOffset++] = (int) ((block1 >> 29) & 511L);
+ values[valuesOffset++] = (int) ((block1 >> 20) & 511L);
+ values[valuesOffset++] = (int) ((block1 >> 11) & 511L);
+ values[valuesOffset++] = (int) ((block1 >> 2) & 511L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 3L) << 7) | (block2 >> 57));
+ values[valuesOffset++] = (int) ((block2 >> 48) & 511L);
+ values[valuesOffset++] = (int) ((block2 >> 39) & 511L);
+ values[valuesOffset++] = (int) ((block2 >> 30) & 511L);
+ values[valuesOffset++] = (int) ((block2 >> 21) & 511L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 511L);
+ values[valuesOffset++] = (int) ((block2 >> 3) & 511L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 7L) << 6) | (block3 >> 58));
+ values[valuesOffset++] = (int) ((block3 >> 49) & 511L);
+ values[valuesOffset++] = (int) ((block3 >> 40) & 511L);
+ values[valuesOffset++] = (int) ((block3 >> 31) & 511L);
+ values[valuesOffset++] = (int) ((block3 >> 22) & 511L);
+ values[valuesOffset++] = (int) ((block3 >> 13) & 511L);
+ values[valuesOffset++] = (int) ((block3 >> 4) & 511L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 15L) << 5) | (block4 >> 59));
+ values[valuesOffset++] = (int) ((block4 >> 50) & 511L);
+ values[valuesOffset++] = (int) ((block4 >> 41) & 511L);
+ values[valuesOffset++] = (int) ((block4 >> 32) & 511L);
+ values[valuesOffset++] = (int) ((block4 >> 23) & 511L);
+ values[valuesOffset++] = (int) ((block4 >> 14) & 511L);
+ values[valuesOffset++] = (int) ((block4 >> 5) & 511L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 31L) << 4) | (block5 >> 60));
+ values[valuesOffset++] = (int) ((block5 >> 51) & 511L);
+ values[valuesOffset++] = (int) ((block5 >> 42) & 511L);
+ values[valuesOffset++] = (int) ((block5 >> 33) & 511L);
+ values[valuesOffset++] = (int) ((block5 >> 24) & 511L);
+ values[valuesOffset++] = (int) ((block5 >> 15) & 511L);
+ values[valuesOffset++] = (int) ((block5 >> 6) & 511L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 63L) << 3) | (block6 >> 61));
+ values[valuesOffset++] = (int) ((block6 >> 52) & 511L);
+ values[valuesOffset++] = (int) ((block6 >> 43) & 511L);
+ values[valuesOffset++] = (int) ((block6 >> 34) & 511L);
+ values[valuesOffset++] = (int) ((block6 >> 25) & 511L);
+ values[valuesOffset++] = (int) ((block6 >> 16) & 511L);
+ values[valuesOffset++] = (int) ((block6 >> 7) & 511L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 127L) << 2) | (block7 >> 62));
+ values[valuesOffset++] = (int) ((block7 >> 53) & 511L);
+ values[valuesOffset++] = (int) ((block7 >> 44) & 511L);
+ values[valuesOffset++] = (int) ((block7 >> 35) & 511L);
+ values[valuesOffset++] = (int) ((block7 >> 26) & 511L);
+ values[valuesOffset++] = (int) ((block7 >> 17) & 511L);
+ values[valuesOffset++] = (int) ((block7 >> 8) & 511L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 255L) << 1) | (block8 >> 63));
+ values[valuesOffset++] = (int) ((block8 >> 54) & 511L);
+ values[valuesOffset++] = (int) ((block8 >> 45) & 511L);
+ values[valuesOffset++] = (int) ((block8 >> 36) & 511L);
+ values[valuesOffset++] = (int) ((block8 >> 27) & 511L);
+ values[valuesOffset++] = (int) ((block8 >> 18) & 511L);
+ values[valuesOffset++] = (int) ((block8 >> 9) & 511L);
+ values[valuesOffset++] = (int) (block8 & 511L);
+ }
+}
+
+static void decode10(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 4; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 54);
+ values[valuesOffset++] = (int) ((block0 >> 44) & 1023L);
+ values[valuesOffset++] = (int) ((block0 >> 34) & 1023L);
+ values[valuesOffset++] = (int) ((block0 >> 24) & 1023L);
+ values[valuesOffset++] = (int) ((block0 >> 14) & 1023L);
+ values[valuesOffset++] = (int) ((block0 >> 4) & 1023L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 15L) << 6) | (block1 >> 58));
+ values[valuesOffset++] = (int) ((block1 >> 48) & 1023L);
+ values[valuesOffset++] = (int) ((block1 >> 38) & 1023L);
+ values[valuesOffset++] = (int) ((block1 >> 28) & 1023L);
+ values[valuesOffset++] = (int) ((block1 >> 18) & 1023L);
+ values[valuesOffset++] = (int) ((block1 >> 8) & 1023L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 255L) << 2) | (block2 >> 62));
+ values[valuesOffset++] = (int) ((block2 >> 52) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >> 42) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >> 32) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >> 22) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 1023L);
+ values[valuesOffset++] = (int) ((block2 >> 2) & 1023L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 3L) << 8) | (block3 >> 56));
+ values[valuesOffset++] = (int) ((block3 >> 46) & 1023L);
+ values[valuesOffset++] = (int) ((block3 >> 36) & 1023L);
+ values[valuesOffset++] = (int) ((block3 >> 26) & 1023L);
+ values[valuesOffset++] = (int) ((block3 >> 16) & 1023L);
+ values[valuesOffset++] = (int) ((block3 >> 6) & 1023L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 63L) << 4) | (block4 >> 60));
+ values[valuesOffset++] = (int) ((block4 >> 50) & 1023L);
+ values[valuesOffset++] = (int) ((block4 >> 40) & 1023L);
+ values[valuesOffset++] = (int) ((block4 >> 30) & 1023L);
+ values[valuesOffset++] = (int) ((block4 >> 20) & 1023L);
+ values[valuesOffset++] = (int) ((block4 >> 10) & 1023L);
+ values[valuesOffset++] = (int) (block4 & 1023L);
+ }
+}
+
+static void decode11(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 53);
+ values[valuesOffset++] = (int) ((block0 >> 42) & 2047L);
+ values[valuesOffset++] = (int) ((block0 >> 31) & 2047L);
+ values[valuesOffset++] = (int) ((block0 >> 20) & 2047L);
+ values[valuesOffset++] = (int) ((block0 >> 9) & 2047L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 511L) << 2) | (block1 >> 62));
+ values[valuesOffset++] = (int) ((block1 >> 51) & 2047L);
+ values[valuesOffset++] = (int) ((block1 >> 40) & 2047L);
+ values[valuesOffset++] = (int) ((block1 >> 29) & 2047L);
+ values[valuesOffset++] = (int) ((block1 >> 18) & 2047L);
+ values[valuesOffset++] = (int) ((block1 >> 7) & 2047L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 127L) << 4) | (block2 >> 60));
+ values[valuesOffset++] = (int) ((block2 >> 49) & 2047L);
+ values[valuesOffset++] = (int) ((block2 >> 38) & 2047L);
+ values[valuesOffset++] = (int) ((block2 >> 27) & 2047L);
+ values[valuesOffset++] = (int) ((block2 >> 16) & 2047L);
+ values[valuesOffset++] = (int) ((block2 >> 5) & 2047L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 31L) << 6) | (block3 >> 58));
+ values[valuesOffset++] = (int) ((block3 >> 47) & 2047L);
+ values[valuesOffset++] = (int) ((block3 >> 36) & 2047L);
+ values[valuesOffset++] = (int) ((block3 >> 25) & 2047L);
+ values[valuesOffset++] = (int) ((block3 >> 14) & 2047L);
+ values[valuesOffset++] = (int) ((block3 >> 3) & 2047L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 7L) << 8) | (block4 >> 56));
+ values[valuesOffset++] = (int) ((block4 >> 45) & 2047L);
+ values[valuesOffset++] = (int) ((block4 >> 34) & 2047L);
+ values[valuesOffset++] = (int) ((block4 >> 23) & 2047L);
+ values[valuesOffset++] = (int) ((block4 >> 12) & 2047L);
+ values[valuesOffset++] = (int) ((block4 >> 1) & 2047L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 1L) << 10) | (block5 >> 54));
+ values[valuesOffset++] = (int) ((block5 >> 43) & 2047L);
+ values[valuesOffset++] = (int) ((block5 >> 32) & 2047L);
+ values[valuesOffset++] = (int) ((block5 >> 21) & 2047L);
+ values[valuesOffset++] = (int) ((block5 >> 10) & 2047L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 1023L) << 1) | (block6 >> 63));
+ values[valuesOffset++] = (int) ((block6 >> 52) & 2047L);
+ values[valuesOffset++] = (int) ((block6 >> 41) & 2047L);
+ values[valuesOffset++] = (int) ((block6 >> 30) & 2047L);
+ values[valuesOffset++] = (int) ((block6 >> 19) & 2047L);
+ values[valuesOffset++] = (int) ((block6 >> 8) & 2047L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 255L) << 3) | (block7 >> 61));
+ values[valuesOffset++] = (int) ((block7 >> 50) & 2047L);
+ values[valuesOffset++] = (int) ((block7 >> 39) & 2047L);
+ values[valuesOffset++] = (int) ((block7 >> 28) & 2047L);
+ values[valuesOffset++] = (int) ((block7 >> 17) & 2047L);
+ values[valuesOffset++] = (int) ((block7 >> 6) & 2047L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 63L) << 5) | (block8 >> 59));
+ values[valuesOffset++] = (int) ((block8 >> 48) & 2047L);
+ values[valuesOffset++] = (int) ((block8 >> 37) & 2047L);
+ values[valuesOffset++] = (int) ((block8 >> 26) & 2047L);
+ values[valuesOffset++] = (int) ((block8 >> 15) & 2047L);
+ values[valuesOffset++] = (int) ((block8 >> 4) & 2047L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 15L) << 7) | (block9 >> 57));
+ values[valuesOffset++] = (int) ((block9 >> 46) & 2047L);
+ values[valuesOffset++] = (int) ((block9 >> 35) & 2047L);
+ values[valuesOffset++] = (int) ((block9 >> 24) & 2047L);
+ values[valuesOffset++] = (int) ((block9 >> 13) & 2047L);
+ values[valuesOffset++] = (int) ((block9 >> 2) & 2047L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 3L) << 9) | (block10 >> 55));
+ values[valuesOffset++] = (int) ((block10 >> 44) & 2047L);
+ values[valuesOffset++] = (int) ((block10 >> 33) & 2047L);
+ values[valuesOffset++] = (int) ((block10 >> 22) & 2047L);
+ values[valuesOffset++] = (int) ((block10 >> 11) & 2047L);
+ values[valuesOffset++] = (int) (block10 & 2047L);
+ }
+}
+
+static void decode12(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 8; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 52);
+ values[valuesOffset++] = (int) ((block0 >> 40) & 4095L);
+ values[valuesOffset++] = (int) ((block0 >> 28) & 4095L);
+ values[valuesOffset++] = (int) ((block0 >> 16) & 4095L);
+ values[valuesOffset++] = (int) ((block0 >> 4) & 4095L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 15L) << 8) | (block1 >> 56));
+ values[valuesOffset++] = (int) ((block1 >> 44) & 4095L);
+ values[valuesOffset++] = (int) ((block1 >> 32) & 4095L);
+ values[valuesOffset++] = (int) ((block1 >> 20) & 4095L);
+ values[valuesOffset++] = (int) ((block1 >> 8) & 4095L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 255L) << 4) | (block2 >> 60));
+ values[valuesOffset++] = (int) ((block2 >> 48) & 4095L);
+ values[valuesOffset++] = (int) ((block2 >> 36) & 4095L);
+ values[valuesOffset++] = (int) ((block2 >> 24) & 4095L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 4095L);
+ values[valuesOffset++] = (int) (block2 & 4095L);
+ }
+}
+
+static void decode13(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 51);
+ values[valuesOffset++] = (int) ((block0 >> 38) & 8191L);
+ values[valuesOffset++] = (int) ((block0 >> 25) & 8191L);
+ values[valuesOffset++] = (int) ((block0 >> 12) & 8191L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 4095L) << 1) | (block1 >> 63));
+ values[valuesOffset++] = (int) ((block1 >> 50) & 8191L);
+ values[valuesOffset++] = (int) ((block1 >> 37) & 8191L);
+ values[valuesOffset++] = (int) ((block1 >> 24) & 8191L);
+ values[valuesOffset++] = (int) ((block1 >> 11) & 8191L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 2047L) << 2) | (block2 >> 62));
+ values[valuesOffset++] = (int) ((block2 >> 49) & 8191L);
+ values[valuesOffset++] = (int) ((block2 >> 36) & 8191L);
+ values[valuesOffset++] = (int) ((block2 >> 23) & 8191L);
+ values[valuesOffset++] = (int) ((block2 >> 10) & 8191L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 1023L) << 3) | (block3 >> 61));
+ values[valuesOffset++] = (int) ((block3 >> 48) & 8191L);
+ values[valuesOffset++] = (int) ((block3 >> 35) & 8191L);
+ values[valuesOffset++] = (int) ((block3 >> 22) & 8191L);
+ values[valuesOffset++] = (int) ((block3 >> 9) & 8191L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 511L) << 4) | (block4 >> 60));
+ values[valuesOffset++] = (int) ((block4 >> 47) & 8191L);
+ values[valuesOffset++] = (int) ((block4 >> 34) & 8191L);
+ values[valuesOffset++] = (int) ((block4 >> 21) & 8191L);
+ values[valuesOffset++] = (int) ((block4 >> 8) & 8191L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 255L) << 5) | (block5 >> 59));
+ values[valuesOffset++] = (int) ((block5 >> 46) & 8191L);
+ values[valuesOffset++] = (int) ((block5 >> 33) & 8191L);
+ values[valuesOffset++] = (int) ((block5 >> 20) & 8191L);
+ values[valuesOffset++] = (int) ((block5 >> 7) & 8191L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 127L) << 6) | (block6 >> 58));
+ values[valuesOffset++] = (int) ((block6 >> 45) & 8191L);
+ values[valuesOffset++] = (int) ((block6 >> 32) & 8191L);
+ values[valuesOffset++] = (int) ((block6 >> 19) & 8191L);
+ values[valuesOffset++] = (int) ((block6 >> 6) & 8191L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 63L) << 7) | (block7 >> 57));
+ values[valuesOffset++] = (int) ((block7 >> 44) & 8191L);
+ values[valuesOffset++] = (int) ((block7 >> 31) & 8191L);
+ values[valuesOffset++] = (int) ((block7 >> 18) & 8191L);
+ values[valuesOffset++] = (int) ((block7 >> 5) & 8191L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 31L) << 8) | (block8 >> 56));
+ values[valuesOffset++] = (int) ((block8 >> 43) & 8191L);
+ values[valuesOffset++] = (int) ((block8 >> 30) & 8191L);
+ values[valuesOffset++] = (int) ((block8 >> 17) & 8191L);
+ values[valuesOffset++] = (int) ((block8 >> 4) & 8191L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 15L) << 9) | (block9 >> 55));
+ values[valuesOffset++] = (int) ((block9 >> 42) & 8191L);
+ values[valuesOffset++] = (int) ((block9 >> 29) & 8191L);
+ values[valuesOffset++] = (int) ((block9 >> 16) & 8191L);
+ values[valuesOffset++] = (int) ((block9 >> 3) & 8191L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 7L) << 10) | (block10 >> 54));
+ values[valuesOffset++] = (int) ((block10 >> 41) & 8191L);
+ values[valuesOffset++] = (int) ((block10 >> 28) & 8191L);
+ values[valuesOffset++] = (int) ((block10 >> 15) & 8191L);
+ values[valuesOffset++] = (int) ((block10 >> 2) & 8191L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 3L) << 11) | (block11 >> 53));
+ values[valuesOffset++] = (int) ((block11 >> 40) & 8191L);
+ values[valuesOffset++] = (int) ((block11 >> 27) & 8191L);
+ values[valuesOffset++] = (int) ((block11 >> 14) & 8191L);
+ values[valuesOffset++] = (int) ((block11 >> 1) & 8191L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 1L) << 12) | (block12 >> 52));
+ values[valuesOffset++] = (int) ((block12 >> 39) & 8191L);
+ values[valuesOffset++] = (int) ((block12 >> 26) & 8191L);
+ values[valuesOffset++] = (int) ((block12 >> 13) & 8191L);
+ values[valuesOffset++] = (int) (block12 & 8191L);
+ }
+}
+
+static void decode14(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 4; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 50);
+ values[valuesOffset++] = (int) ((block0 >> 36) & 16383L);
+ values[valuesOffset++] = (int) ((block0 >> 22) & 16383L);
+ values[valuesOffset++] = (int) ((block0 >> 8) & 16383L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 255L) << 6) | (block1 >> 58));
+ values[valuesOffset++] = (int) ((block1 >> 44) & 16383L);
+ values[valuesOffset++] = (int) ((block1 >> 30) & 16383L);
+ values[valuesOffset++] = (int) ((block1 >> 16) & 16383L);
+ values[valuesOffset++] = (int) ((block1 >> 2) & 16383L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 3L) << 12) | (block2 >> 52));
+ values[valuesOffset++] = (int) ((block2 >> 38) & 16383L);
+ values[valuesOffset++] = (int) ((block2 >> 24) & 16383L);
+ values[valuesOffset++] = (int) ((block2 >> 10) & 16383L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 1023L) << 4) | (block3 >> 60));
+ values[valuesOffset++] = (int) ((block3 >> 46) & 16383L);
+ values[valuesOffset++] = (int) ((block3 >> 32) & 16383L);
+ values[valuesOffset++] = (int) ((block3 >> 18) & 16383L);
+ values[valuesOffset++] = (int) ((block3 >> 4) & 16383L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 15L) << 10) | (block4 >> 54));
+ values[valuesOffset++] = (int) ((block4 >> 40) & 16383L);
+ values[valuesOffset++] = (int) ((block4 >> 26) & 16383L);
+ values[valuesOffset++] = (int) ((block4 >> 12) & 16383L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 4095L) << 2) | (block5 >> 62));
+ values[valuesOffset++] = (int) ((block5 >> 48) & 16383L);
+ values[valuesOffset++] = (int) ((block5 >> 34) & 16383L);
+ values[valuesOffset++] = (int) ((block5 >> 20) & 16383L);
+ values[valuesOffset++] = (int) ((block5 >> 6) & 16383L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 63L) << 8) | (block6 >> 56));
+ values[valuesOffset++] = (int) ((block6 >> 42) & 16383L);
+ values[valuesOffset++] = (int) ((block6 >> 28) & 16383L);
+ values[valuesOffset++] = (int) ((block6 >> 14) & 16383L);
+ values[valuesOffset++] = (int) (block6 & 16383L);
+ }
+}
+
+static void decode15(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 49);
+ values[valuesOffset++] = (int) ((block0 >> 34) & 32767L);
+ values[valuesOffset++] = (int) ((block0 >> 19) & 32767L);
+ values[valuesOffset++] = (int) ((block0 >> 4) & 32767L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 15L) << 11) | (block1 >> 53));
+ values[valuesOffset++] = (int) ((block1 >> 38) & 32767L);
+ values[valuesOffset++] = (int) ((block1 >> 23) & 32767L);
+ values[valuesOffset++] = (int) ((block1 >> 8) & 32767L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 255L) << 7) | (block2 >> 57));
+ values[valuesOffset++] = (int) ((block2 >> 42) & 32767L);
+ values[valuesOffset++] = (int) ((block2 >> 27) & 32767L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 32767L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 4095L) << 3) | (block3 >> 61));
+ values[valuesOffset++] = (int) ((block3 >> 46) & 32767L);
+ values[valuesOffset++] = (int) ((block3 >> 31) & 32767L);
+ values[valuesOffset++] = (int) ((block3 >> 16) & 32767L);
+ values[valuesOffset++] = (int) ((block3 >> 1) & 32767L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 1L) << 14) | (block4 >> 50));
+ values[valuesOffset++] = (int) ((block4 >> 35) & 32767L);
+ values[valuesOffset++] = (int) ((block4 >> 20) & 32767L);
+ values[valuesOffset++] = (int) ((block4 >> 5) & 32767L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 31L) << 10) | (block5 >> 54));
+ values[valuesOffset++] = (int) ((block5 >> 39) & 32767L);
+ values[valuesOffset++] = (int) ((block5 >> 24) & 32767L);
+ values[valuesOffset++] = (int) ((block5 >> 9) & 32767L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 511L) << 6) | (block6 >> 58));
+ values[valuesOffset++] = (int) ((block6 >> 43) & 32767L);
+ values[valuesOffset++] = (int) ((block6 >> 28) & 32767L);
+ values[valuesOffset++] = (int) ((block6 >> 13) & 32767L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 8191L) << 2) | (block7 >> 62));
+ values[valuesOffset++] = (int) ((block7 >> 47) & 32767L);
+ values[valuesOffset++] = (int) ((block7 >> 32) & 32767L);
+ values[valuesOffset++] = (int) ((block7 >> 17) & 32767L);
+ values[valuesOffset++] = (int) ((block7 >> 2) & 32767L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 3L) << 13) | (block8 >> 51));
+ values[valuesOffset++] = (int) ((block8 >> 36) & 32767L);
+ values[valuesOffset++] = (int) ((block8 >> 21) & 32767L);
+ values[valuesOffset++] = (int) ((block8 >> 6) & 32767L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 63L) << 9) | (block9 >> 55));
+ values[valuesOffset++] = (int) ((block9 >> 40) & 32767L);
+ values[valuesOffset++] = (int) ((block9 >> 25) & 32767L);
+ values[valuesOffset++] = (int) ((block9 >> 10) & 32767L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 1023L) << 5) | (block10 >> 59));
+ values[valuesOffset++] = (int) ((block10 >> 44) & 32767L);
+ values[valuesOffset++] = (int) ((block10 >> 29) & 32767L);
+ values[valuesOffset++] = (int) ((block10 >> 14) & 32767L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 16383L) << 1) | (block11 >> 63));
+ values[valuesOffset++] = (int) ((block11 >> 48) & 32767L);
+ values[valuesOffset++] = (int) ((block11 >> 33) & 32767L);
+ values[valuesOffset++] = (int) ((block11 >> 18) & 32767L);
+ values[valuesOffset++] = (int) ((block11 >> 3) & 32767L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 7L) << 12) | (block12 >> 52));
+ values[valuesOffset++] = (int) ((block12 >> 37) & 32767L);
+ values[valuesOffset++] = (int) ((block12 >> 22) & 32767L);
+ values[valuesOffset++] = (int) ((block12 >> 7) & 32767L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 127L) << 8) | (block13 >> 56));
+ values[valuesOffset++] = (int) ((block13 >> 41) & 32767L);
+ values[valuesOffset++] = (int) ((block13 >> 26) & 32767L);
+ values[valuesOffset++] = (int) ((block13 >> 11) & 32767L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 2047L) << 4) | (block14 >> 60));
+ values[valuesOffset++] = (int) ((block14 >> 45) & 32767L);
+ values[valuesOffset++] = (int) ((block14 >> 30) & 32767L);
+ values[valuesOffset++] = (int) ((block14 >> 15) & 32767L);
+ values[valuesOffset++] = (int) (block14 & 32767L);
+ }
+}
+
+static void decode16(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 32; ++i) {
+ unsigned long block = blocks[blocksOffset++];
+ block = __bswap_64(block);
+ for (int shift = 48; shift >= 0; shift -= 16) {
+ values[valuesOffset++] = (int) ((block >> shift) & 65535);
+ }
+ }
+}
+
+static void decode17(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 47);
+ values[valuesOffset++] = (int) ((block0 >> 30) & 131071L);
+ values[valuesOffset++] = (int) ((block0 >> 13) & 131071L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 8191L) << 4) | (block1 >> 60));
+ values[valuesOffset++] = (int) ((block1 >> 43) & 131071L);
+ values[valuesOffset++] = (int) ((block1 >> 26) & 131071L);
+ values[valuesOffset++] = (int) ((block1 >> 9) & 131071L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 511L) << 8) | (block2 >> 56));
+ values[valuesOffset++] = (int) ((block2 >> 39) & 131071L);
+ values[valuesOffset++] = (int) ((block2 >> 22) & 131071L);
+ values[valuesOffset++] = (int) ((block2 >> 5) & 131071L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 31L) << 12) | (block3 >> 52));
+ values[valuesOffset++] = (int) ((block3 >> 35) & 131071L);
+ values[valuesOffset++] = (int) ((block3 >> 18) & 131071L);
+ values[valuesOffset++] = (int) ((block3 >> 1) & 131071L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 1L) << 16) | (block4 >> 48));
+ values[valuesOffset++] = (int) ((block4 >> 31) & 131071L);
+ values[valuesOffset++] = (int) ((block4 >> 14) & 131071L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 16383L) << 3) | (block5 >> 61));
+ values[valuesOffset++] = (int) ((block5 >> 44) & 131071L);
+ values[valuesOffset++] = (int) ((block5 >> 27) & 131071L);
+ values[valuesOffset++] = (int) ((block5 >> 10) & 131071L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 1023L) << 7) | (block6 >> 57));
+ values[valuesOffset++] = (int) ((block6 >> 40) & 131071L);
+ values[valuesOffset++] = (int) ((block6 >> 23) & 131071L);
+ values[valuesOffset++] = (int) ((block6 >> 6) & 131071L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 63L) << 11) | (block7 >> 53));
+ values[valuesOffset++] = (int) ((block7 >> 36) & 131071L);
+ values[valuesOffset++] = (int) ((block7 >> 19) & 131071L);
+ values[valuesOffset++] = (int) ((block7 >> 2) & 131071L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 3L) << 15) | (block8 >> 49));
+ values[valuesOffset++] = (int) ((block8 >> 32) & 131071L);
+ values[valuesOffset++] = (int) ((block8 >> 15) & 131071L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 32767L) << 2) | (block9 >> 62));
+ values[valuesOffset++] = (int) ((block9 >> 45) & 131071L);
+ values[valuesOffset++] = (int) ((block9 >> 28) & 131071L);
+ values[valuesOffset++] = (int) ((block9 >> 11) & 131071L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 2047L) << 6) | (block10 >> 58));
+ values[valuesOffset++] = (int) ((block10 >> 41) & 131071L);
+ values[valuesOffset++] = (int) ((block10 >> 24) & 131071L);
+ values[valuesOffset++] = (int) ((block10 >> 7) & 131071L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 127L) << 10) | (block11 >> 54));
+ values[valuesOffset++] = (int) ((block11 >> 37) & 131071L);
+ values[valuesOffset++] = (int) ((block11 >> 20) & 131071L);
+ values[valuesOffset++] = (int) ((block11 >> 3) & 131071L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 7L) << 14) | (block12 >> 50));
+ values[valuesOffset++] = (int) ((block12 >> 33) & 131071L);
+ values[valuesOffset++] = (int) ((block12 >> 16) & 131071L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 65535L) << 1) | (block13 >> 63));
+ values[valuesOffset++] = (int) ((block13 >> 46) & 131071L);
+ values[valuesOffset++] = (int) ((block13 >> 29) & 131071L);
+ values[valuesOffset++] = (int) ((block13 >> 12) & 131071L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 4095L) << 5) | (block14 >> 59));
+ values[valuesOffset++] = (int) ((block14 >> 42) & 131071L);
+ values[valuesOffset++] = (int) ((block14 >> 25) & 131071L);
+ values[valuesOffset++] = (int) ((block14 >> 8) & 131071L);
+ unsigned long block15 = blocks[blocksOffset++];
+ block15 = __bswap_64(block15);
+ values[valuesOffset++] = (int) (((block14 & 255L) << 9) | (block15 >> 55));
+ values[valuesOffset++] = (int) ((block15 >> 38) & 131071L);
+ values[valuesOffset++] = (int) ((block15 >> 21) & 131071L);
+ values[valuesOffset++] = (int) ((block15 >> 4) & 131071L);
+ unsigned long block16 = blocks[blocksOffset++];
+ block16 = __bswap_64(block16);
+ values[valuesOffset++] = (int) (((block15 & 15L) << 13) | (block16 >> 51));
+ values[valuesOffset++] = (int) ((block16 >> 34) & 131071L);
+ values[valuesOffset++] = (int) ((block16 >> 17) & 131071L);
+ values[valuesOffset++] = (int) (block16 & 131071L);
+ }
+}
+
+static void decode18(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 4; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 46);
+ values[valuesOffset++] = (int) ((block0 >> 28) & 262143L);
+ values[valuesOffset++] = (int) ((block0 >> 10) & 262143L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 1023L) << 8) | (block1 >> 56));
+ values[valuesOffset++] = (int) ((block1 >> 38) & 262143L);
+ values[valuesOffset++] = (int) ((block1 >> 20) & 262143L);
+ values[valuesOffset++] = (int) ((block1 >> 2) & 262143L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 3L) << 16) | (block2 >> 48));
+ values[valuesOffset++] = (int) ((block2 >> 30) & 262143L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 262143L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 4095L) << 6) | (block3 >> 58));
+ values[valuesOffset++] = (int) ((block3 >> 40) & 262143L);
+ values[valuesOffset++] = (int) ((block3 >> 22) & 262143L);
+ values[valuesOffset++] = (int) ((block3 >> 4) & 262143L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 15L) << 14) | (block4 >> 50));
+ values[valuesOffset++] = (int) ((block4 >> 32) & 262143L);
+ values[valuesOffset++] = (int) ((block4 >> 14) & 262143L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 16383L) << 4) | (block5 >> 60));
+ values[valuesOffset++] = (int) ((block5 >> 42) & 262143L);
+ values[valuesOffset++] = (int) ((block5 >> 24) & 262143L);
+ values[valuesOffset++] = (int) ((block5 >> 6) & 262143L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 63L) << 12) | (block6 >> 52));
+ values[valuesOffset++] = (int) ((block6 >> 34) & 262143L);
+ values[valuesOffset++] = (int) ((block6 >> 16) & 262143L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 65535L) << 2) | (block7 >> 62));
+ values[valuesOffset++] = (int) ((block7 >> 44) & 262143L);
+ values[valuesOffset++] = (int) ((block7 >> 26) & 262143L);
+ values[valuesOffset++] = (int) ((block7 >> 8) & 262143L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 255L) << 10) | (block8 >> 54));
+ values[valuesOffset++] = (int) ((block8 >> 36) & 262143L);
+ values[valuesOffset++] = (int) ((block8 >> 18) & 262143L);
+ values[valuesOffset++] = (int) (block8 & 262143L);
+ }
+}
+
+static void decode19(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 45);
+ values[valuesOffset++] = (int) ((block0 >> 26) & 524287L);
+ values[valuesOffset++] = (int) ((block0 >> 7) & 524287L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 127L) << 12) | (block1 >> 52));
+ values[valuesOffset++] = (int) ((block1 >> 33) & 524287L);
+ values[valuesOffset++] = (int) ((block1 >> 14) & 524287L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 16383L) << 5) | (block2 >> 59));
+ values[valuesOffset++] = (int) ((block2 >> 40) & 524287L);
+ values[valuesOffset++] = (int) ((block2 >> 21) & 524287L);
+ values[valuesOffset++] = (int) ((block2 >> 2) & 524287L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 3L) << 17) | (block3 >> 47));
+ values[valuesOffset++] = (int) ((block3 >> 28) & 524287L);
+ values[valuesOffset++] = (int) ((block3 >> 9) & 524287L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 511L) << 10) | (block4 >> 54));
+ values[valuesOffset++] = (int) ((block4 >> 35) & 524287L);
+ values[valuesOffset++] = (int) ((block4 >> 16) & 524287L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 65535L) << 3) | (block5 >> 61));
+ values[valuesOffset++] = (int) ((block5 >> 42) & 524287L);
+ values[valuesOffset++] = (int) ((block5 >> 23) & 524287L);
+ values[valuesOffset++] = (int) ((block5 >> 4) & 524287L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 15L) << 15) | (block6 >> 49));
+ values[valuesOffset++] = (int) ((block6 >> 30) & 524287L);
+ values[valuesOffset++] = (int) ((block6 >> 11) & 524287L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 2047L) << 8) | (block7 >> 56));
+ values[valuesOffset++] = (int) ((block7 >> 37) & 524287L);
+ values[valuesOffset++] = (int) ((block7 >> 18) & 524287L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 262143L) << 1) | (block8 >> 63));
+ values[valuesOffset++] = (int) ((block8 >> 44) & 524287L);
+ values[valuesOffset++] = (int) ((block8 >> 25) & 524287L);
+ values[valuesOffset++] = (int) ((block8 >> 6) & 524287L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 63L) << 13) | (block9 >> 51));
+ values[valuesOffset++] = (int) ((block9 >> 32) & 524287L);
+ values[valuesOffset++] = (int) ((block9 >> 13) & 524287L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 8191L) << 6) | (block10 >> 58));
+ values[valuesOffset++] = (int) ((block10 >> 39) & 524287L);
+ values[valuesOffset++] = (int) ((block10 >> 20) & 524287L);
+ values[valuesOffset++] = (int) ((block10 >> 1) & 524287L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 1L) << 18) | (block11 >> 46));
+ values[valuesOffset++] = (int) ((block11 >> 27) & 524287L);
+ values[valuesOffset++] = (int) ((block11 >> 8) & 524287L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 255L) << 11) | (block12 >> 53));
+ values[valuesOffset++] = (int) ((block12 >> 34) & 524287L);
+ values[valuesOffset++] = (int) ((block12 >> 15) & 524287L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 32767L) << 4) | (block13 >> 60));
+ values[valuesOffset++] = (int) ((block13 >> 41) & 524287L);
+ values[valuesOffset++] = (int) ((block13 >> 22) & 524287L);
+ values[valuesOffset++] = (int) ((block13 >> 3) & 524287L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 7L) << 16) | (block14 >> 48));
+ values[valuesOffset++] = (int) ((block14 >> 29) & 524287L);
+ values[valuesOffset++] = (int) ((block14 >> 10) & 524287L);
+ unsigned long block15 = blocks[blocksOffset++];
+ block15 = __bswap_64(block15);
+ values[valuesOffset++] = (int) (((block14 & 1023L) << 9) | (block15 >> 55));
+ values[valuesOffset++] = (int) ((block15 >> 36) & 524287L);
+ values[valuesOffset++] = (int) ((block15 >> 17) & 524287L);
+ unsigned long block16 = blocks[blocksOffset++];
+ block16 = __bswap_64(block16);
+ values[valuesOffset++] = (int) (((block15 & 131071L) << 2) | (block16 >> 62));
+ values[valuesOffset++] = (int) ((block16 >> 43) & 524287L);
+ values[valuesOffset++] = (int) ((block16 >> 24) & 524287L);
+ values[valuesOffset++] = (int) ((block16 >> 5) & 524287L);
+ unsigned long block17 = blocks[blocksOffset++];
+ block17 = __bswap_64(block17);
+ values[valuesOffset++] = (int) (((block16 & 31L) << 14) | (block17 >> 50));
+ values[valuesOffset++] = (int) ((block17 >> 31) & 524287L);
+ values[valuesOffset++] = (int) ((block17 >> 12) & 524287L);
+ unsigned long block18 = blocks[blocksOffset++];
+ block18 = __bswap_64(block18);
+ values[valuesOffset++] = (int) (((block17 & 4095L) << 7) | (block18 >> 57));
+ values[valuesOffset++] = (int) ((block18 >> 38) & 524287L);
+ values[valuesOffset++] = (int) ((block18 >> 19) & 524287L);
+ values[valuesOffset++] = (int) (block18 & 524287L);
+ }
+}
+
+static void decode20(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 8; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 44);
+ values[valuesOffset++] = (int) ((block0 >> 24) & 1048575L);
+ values[valuesOffset++] = (int) ((block0 >> 4) & 1048575L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 15L) << 16) | (block1 >> 48));
+ values[valuesOffset++] = (int) ((block1 >> 28) & 1048575L);
+ values[valuesOffset++] = (int) ((block1 >> 8) & 1048575L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 255L) << 12) | (block2 >> 52));
+ values[valuesOffset++] = (int) ((block2 >> 32) & 1048575L);
+ values[valuesOffset++] = (int) ((block2 >> 12) & 1048575L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 4095L) << 8) | (block3 >> 56));
+ values[valuesOffset++] = (int) ((block3 >> 36) & 1048575L);
+ values[valuesOffset++] = (int) ((block3 >> 16) & 1048575L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 65535L) << 4) | (block4 >> 60));
+ values[valuesOffset++] = (int) ((block4 >> 40) & 1048575L);
+ values[valuesOffset++] = (int) ((block4 >> 20) & 1048575L);
+ values[valuesOffset++] = (int) (block4 & 1048575L);
+ }
+}
+
+static void decode21(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 43);
+ values[valuesOffset++] = (int) ((block0 >> 22) & 2097151L);
+ values[valuesOffset++] = (int) ((block0 >> 1) & 2097151L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 1L) << 20) | (block1 >> 44));
+ values[valuesOffset++] = (int) ((block1 >> 23) & 2097151L);
+ values[valuesOffset++] = (int) ((block1 >> 2) & 2097151L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 3L) << 19) | (block2 >> 45));
+ values[valuesOffset++] = (int) ((block2 >> 24) & 2097151L);
+ values[valuesOffset++] = (int) ((block2 >> 3) & 2097151L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 7L) << 18) | (block3 >> 46));
+ values[valuesOffset++] = (int) ((block3 >> 25) & 2097151L);
+ values[valuesOffset++] = (int) ((block3 >> 4) & 2097151L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 15L) << 17) | (block4 >> 47));
+ values[valuesOffset++] = (int) ((block4 >> 26) & 2097151L);
+ values[valuesOffset++] = (int) ((block4 >> 5) & 2097151L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 31L) << 16) | (block5 >> 48));
+ values[valuesOffset++] = (int) ((block5 >> 27) & 2097151L);
+ values[valuesOffset++] = (int) ((block5 >> 6) & 2097151L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 63L) << 15) | (block6 >> 49));
+ values[valuesOffset++] = (int) ((block6 >> 28) & 2097151L);
+ values[valuesOffset++] = (int) ((block6 >> 7) & 2097151L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 127L) << 14) | (block7 >> 50));
+ values[valuesOffset++] = (int) ((block7 >> 29) & 2097151L);
+ values[valuesOffset++] = (int) ((block7 >> 8) & 2097151L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 255L) << 13) | (block8 >> 51));
+ values[valuesOffset++] = (int) ((block8 >> 30) & 2097151L);
+ values[valuesOffset++] = (int) ((block8 >> 9) & 2097151L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 511L) << 12) | (block9 >> 52));
+ values[valuesOffset++] = (int) ((block9 >> 31) & 2097151L);
+ values[valuesOffset++] = (int) ((block9 >> 10) & 2097151L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 1023L) << 11) | (block10 >> 53));
+ values[valuesOffset++] = (int) ((block10 >> 32) & 2097151L);
+ values[valuesOffset++] = (int) ((block10 >> 11) & 2097151L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 2047L) << 10) | (block11 >> 54));
+ values[valuesOffset++] = (int) ((block11 >> 33) & 2097151L);
+ values[valuesOffset++] = (int) ((block11 >> 12) & 2097151L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 4095L) << 9) | (block12 >> 55));
+ values[valuesOffset++] = (int) ((block12 >> 34) & 2097151L);
+ values[valuesOffset++] = (int) ((block12 >> 13) & 2097151L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 8191L) << 8) | (block13 >> 56));
+ values[valuesOffset++] = (int) ((block13 >> 35) & 2097151L);
+ values[valuesOffset++] = (int) ((block13 >> 14) & 2097151L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 16383L) << 7) | (block14 >> 57));
+ values[valuesOffset++] = (int) ((block14 >> 36) & 2097151L);
+ values[valuesOffset++] = (int) ((block14 >> 15) & 2097151L);
+ unsigned long block15 = blocks[blocksOffset++];
+ block15 = __bswap_64(block15);
+ values[valuesOffset++] = (int) (((block14 & 32767L) << 6) | (block15 >> 58));
+ values[valuesOffset++] = (int) ((block15 >> 37) & 2097151L);
+ values[valuesOffset++] = (int) ((block15 >> 16) & 2097151L);
+ unsigned long block16 = blocks[blocksOffset++];
+ block16 = __bswap_64(block16);
+ values[valuesOffset++] = (int) (((block15 & 65535L) << 5) | (block16 >> 59));
+ values[valuesOffset++] = (int) ((block16 >> 38) & 2097151L);
+ values[valuesOffset++] = (int) ((block16 >> 17) & 2097151L);
+ unsigned long block17 = blocks[blocksOffset++];
+ block17 = __bswap_64(block17);
+ values[valuesOffset++] = (int) (((block16 & 131071L) << 4) | (block17 >> 60));
+ values[valuesOffset++] = (int) ((block17 >> 39) & 2097151L);
+ values[valuesOffset++] = (int) ((block17 >> 18) & 2097151L);
+ unsigned long block18 = blocks[blocksOffset++];
+ block18 = __bswap_64(block18);
+ values[valuesOffset++] = (int) (((block17 & 262143L) << 3) | (block18 >> 61));
+ values[valuesOffset++] = (int) ((block18 >> 40) & 2097151L);
+ values[valuesOffset++] = (int) ((block18 >> 19) & 2097151L);
+ unsigned long block19 = blocks[blocksOffset++];
+ block19 = __bswap_64(block19);
+ values[valuesOffset++] = (int) (((block18 & 524287L) << 2) | (block19 >> 62));
+ values[valuesOffset++] = (int) ((block19 >> 41) & 2097151L);
+ values[valuesOffset++] = (int) ((block19 >> 20) & 2097151L);
+ unsigned long block20 = blocks[blocksOffset++];
+ block20 = __bswap_64(block20);
+ values[valuesOffset++] = (int) (((block19 & 1048575L) << 1) | (block20 >> 63));
+ values[valuesOffset++] = (int) ((block20 >> 42) & 2097151L);
+ values[valuesOffset++] = (int) ((block20 >> 21) & 2097151L);
+ values[valuesOffset++] = (int) (block20 & 2097151L);
+ }
+}
+
+static void decode22(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 4; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 42);
+ values[valuesOffset++] = (int) ((block0 >> 20) & 4194303L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 1048575L) << 2) | (block1 >> 62));
+ values[valuesOffset++] = (int) ((block1 >> 40) & 4194303L);
+ values[valuesOffset++] = (int) ((block1 >> 18) & 4194303L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 262143L) << 4) | (block2 >> 60));
+ values[valuesOffset++] = (int) ((block2 >> 38) & 4194303L);
+ values[valuesOffset++] = (int) ((block2 >> 16) & 4194303L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 65535L) << 6) | (block3 >> 58));
+ values[valuesOffset++] = (int) ((block3 >> 36) & 4194303L);
+ values[valuesOffset++] = (int) ((block3 >> 14) & 4194303L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 16383L) << 8) | (block4 >> 56));
+ values[valuesOffset++] = (int) ((block4 >> 34) & 4194303L);
+ values[valuesOffset++] = (int) ((block4 >> 12) & 4194303L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 4095L) << 10) | (block5 >> 54));
+ values[valuesOffset++] = (int) ((block5 >> 32) & 4194303L);
+ values[valuesOffset++] = (int) ((block5 >> 10) & 4194303L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 1023L) << 12) | (block6 >> 52));
+ values[valuesOffset++] = (int) ((block6 >> 30) & 4194303L);
+ values[valuesOffset++] = (int) ((block6 >> 8) & 4194303L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 255L) << 14) | (block7 >> 50));
+ values[valuesOffset++] = (int) ((block7 >> 28) & 4194303L);
+ values[valuesOffset++] = (int) ((block7 >> 6) & 4194303L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 63L) << 16) | (block8 >> 48));
+ values[valuesOffset++] = (int) ((block8 >> 26) & 4194303L);
+ values[valuesOffset++] = (int) ((block8 >> 4) & 4194303L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 15L) << 18) | (block9 >> 46));
+ values[valuesOffset++] = (int) ((block9 >> 24) & 4194303L);
+ values[valuesOffset++] = (int) ((block9 >> 2) & 4194303L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 3L) << 20) | (block10 >> 44));
+ values[valuesOffset++] = (int) ((block10 >> 22) & 4194303L);
+ values[valuesOffset++] = (int) (block10 & 4194303L);
+ }
+}
+
+static void decode23(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 41);
+ values[valuesOffset++] = (int) ((block0 >> 18) & 8388607L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 262143L) << 5) | (block1 >> 59));
+ values[valuesOffset++] = (int) ((block1 >> 36) & 8388607L);
+ values[valuesOffset++] = (int) ((block1 >> 13) & 8388607L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 8191L) << 10) | (block2 >> 54));
+ values[valuesOffset++] = (int) ((block2 >> 31) & 8388607L);
+ values[valuesOffset++] = (int) ((block2 >> 8) & 8388607L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 255L) << 15) | (block3 >> 49));
+ values[valuesOffset++] = (int) ((block3 >> 26) & 8388607L);
+ values[valuesOffset++] = (int) ((block3 >> 3) & 8388607L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 7L) << 20) | (block4 >> 44));
+ values[valuesOffset++] = (int) ((block4 >> 21) & 8388607L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 2097151L) << 2) | (block5 >> 62));
+ values[valuesOffset++] = (int) ((block5 >> 39) & 8388607L);
+ values[valuesOffset++] = (int) ((block5 >> 16) & 8388607L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 65535L) << 7) | (block6 >> 57));
+ values[valuesOffset++] = (int) ((block6 >> 34) & 8388607L);
+ values[valuesOffset++] = (int) ((block6 >> 11) & 8388607L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 2047L) << 12) | (block7 >> 52));
+ values[valuesOffset++] = (int) ((block7 >> 29) & 8388607L);
+ values[valuesOffset++] = (int) ((block7 >> 6) & 8388607L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 63L) << 17) | (block8 >> 47));
+ values[valuesOffset++] = (int) ((block8 >> 24) & 8388607L);
+ values[valuesOffset++] = (int) ((block8 >> 1) & 8388607L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 1L) << 22) | (block9 >> 42));
+ values[valuesOffset++] = (int) ((block9 >> 19) & 8388607L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 524287L) << 4) | (block10 >> 60));
+ values[valuesOffset++] = (int) ((block10 >> 37) & 8388607L);
+ values[valuesOffset++] = (int) ((block10 >> 14) & 8388607L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 16383L) << 9) | (block11 >> 55));
+ values[valuesOffset++] = (int) ((block11 >> 32) & 8388607L);
+ values[valuesOffset++] = (int) ((block11 >> 9) & 8388607L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 511L) << 14) | (block12 >> 50));
+ values[valuesOffset++] = (int) ((block12 >> 27) & 8388607L);
+ values[valuesOffset++] = (int) ((block12 >> 4) & 8388607L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 15L) << 19) | (block13 >> 45));
+ values[valuesOffset++] = (int) ((block13 >> 22) & 8388607L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 4194303L) << 1) | (block14 >> 63));
+ values[valuesOffset++] = (int) ((block14 >> 40) & 8388607L);
+ values[valuesOffset++] = (int) ((block14 >> 17) & 8388607L);
+ unsigned long block15 = blocks[blocksOffset++];
+ block15 = __bswap_64(block15);
+ values[valuesOffset++] = (int) (((block14 & 131071L) << 6) | (block15 >> 58));
+ values[valuesOffset++] = (int) ((block15 >> 35) & 8388607L);
+ values[valuesOffset++] = (int) ((block15 >> 12) & 8388607L);
+ unsigned long block16 = blocks[blocksOffset++];
+ block16 = __bswap_64(block16);
+ values[valuesOffset++] = (int) (((block15 & 4095L) << 11) | (block16 >> 53));
+ values[valuesOffset++] = (int) ((block16 >> 30) & 8388607L);
+ values[valuesOffset++] = (int) ((block16 >> 7) & 8388607L);
+ unsigned long block17 = blocks[blocksOffset++];
+ block17 = __bswap_64(block17);
+ values[valuesOffset++] = (int) (((block16 & 127L) << 16) | (block17 >> 48));
+ values[valuesOffset++] = (int) ((block17 >> 25) & 8388607L);
+ values[valuesOffset++] = (int) ((block17 >> 2) & 8388607L);
+ unsigned long block18 = blocks[blocksOffset++];
+ block18 = __bswap_64(block18);
+ values[valuesOffset++] = (int) (((block17 & 3L) << 21) | (block18 >> 43));
+ values[valuesOffset++] = (int) ((block18 >> 20) & 8388607L);
+ unsigned long block19 = blocks[blocksOffset++];
+ block19 = __bswap_64(block19);
+ values[valuesOffset++] = (int) (((block18 & 1048575L) << 3) | (block19 >> 61));
+ values[valuesOffset++] = (int) ((block19 >> 38) & 8388607L);
+ values[valuesOffset++] = (int) ((block19 >> 15) & 8388607L);
+ unsigned long block20 = blocks[blocksOffset++];
+ block20 = __bswap_64(block20);
+ values[valuesOffset++] = (int) (((block19 & 32767L) << 8) | (block20 >> 56));
+ values[valuesOffset++] = (int) ((block20 >> 33) & 8388607L);
+ values[valuesOffset++] = (int) ((block20 >> 10) & 8388607L);
+ unsigned long block21 = blocks[blocksOffset++];
+ block21 = __bswap_64(block21);
+ values[valuesOffset++] = (int) (((block20 & 1023L) << 13) | (block21 >> 51));
+ values[valuesOffset++] = (int) ((block21 >> 28) & 8388607L);
+ values[valuesOffset++] = (int) ((block21 >> 5) & 8388607L);
+ unsigned long block22 = blocks[blocksOffset++];
+ block22 = __bswap_64(block22);
+ values[valuesOffset++] = (int) (((block21 & 31L) << 18) | (block22 >> 46));
+ values[valuesOffset++] = (int) ((block22 >> 23) & 8388607L);
+ values[valuesOffset++] = (int) (block22 & 8388607L);
+ }
+}
+
+static void decode24(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 16; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 40);
+ values[valuesOffset++] = (int) ((block0 >> 16) & 16777215L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 65535L) << 8) | (block1 >> 56));
+ values[valuesOffset++] = (int) ((block1 >> 32) & 16777215L);
+ values[valuesOffset++] = (int) ((block1 >> 8) & 16777215L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 255L) << 16) | (block2 >> 48));
+ values[valuesOffset++] = (int) ((block2 >> 24) & 16777215L);
+ values[valuesOffset++] = (int) (block2 & 16777215L);
+ }
+}
+
+static void decode25(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 39);
+ values[valuesOffset++] = (int) ((block0 >> 14) & 33554431L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 16383L) << 11) | (block1 >> 53));
+ values[valuesOffset++] = (int) ((block1 >> 28) & 33554431L);
+ values[valuesOffset++] = (int) ((block1 >> 3) & 33554431L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 7L) << 22) | (block2 >> 42));
+ values[valuesOffset++] = (int) ((block2 >> 17) & 33554431L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 131071L) << 8) | (block3 >> 56));
+ values[valuesOffset++] = (int) ((block3 >> 31) & 33554431L);
+ values[valuesOffset++] = (int) ((block3 >> 6) & 33554431L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 63L) << 19) | (block4 >> 45));
+ values[valuesOffset++] = (int) ((block4 >> 20) & 33554431L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 1048575L) << 5) | (block5 >> 59));
+ values[valuesOffset++] = (int) ((block5 >> 34) & 33554431L);
+ values[valuesOffset++] = (int) ((block5 >> 9) & 33554431L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 511L) << 16) | (block6 >> 48));
+ values[valuesOffset++] = (int) ((block6 >> 23) & 33554431L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 8388607L) << 2) | (block7 >> 62));
+ values[valuesOffset++] = (int) ((block7 >> 37) & 33554431L);
+ values[valuesOffset++] = (int) ((block7 >> 12) & 33554431L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 4095L) << 13) | (block8 >> 51));
+ values[valuesOffset++] = (int) ((block8 >> 26) & 33554431L);
+ values[valuesOffset++] = (int) ((block8 >> 1) & 33554431L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 1L) << 24) | (block9 >> 40));
+ values[valuesOffset++] = (int) ((block9 >> 15) & 33554431L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 32767L) << 10) | (block10 >> 54));
+ values[valuesOffset++] = (int) ((block10 >> 29) & 33554431L);
+ values[valuesOffset++] = (int) ((block10 >> 4) & 33554431L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 15L) << 21) | (block11 >> 43));
+ values[valuesOffset++] = (int) ((block11 >> 18) & 33554431L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 262143L) << 7) | (block12 >> 57));
+ values[valuesOffset++] = (int) ((block12 >> 32) & 33554431L);
+ values[valuesOffset++] = (int) ((block12 >> 7) & 33554431L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 127L) << 18) | (block13 >> 46));
+ values[valuesOffset++] = (int) ((block13 >> 21) & 33554431L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 2097151L) << 4) | (block14 >> 60));
+ values[valuesOffset++] = (int) ((block14 >> 35) & 33554431L);
+ values[valuesOffset++] = (int) ((block14 >> 10) & 33554431L);
+ unsigned long block15 = blocks[blocksOffset++];
+ block15 = __bswap_64(block15);
+ values[valuesOffset++] = (int) (((block14 & 1023L) << 15) | (block15 >> 49));
+ values[valuesOffset++] = (int) ((block15 >> 24) & 33554431L);
+ unsigned long block16 = blocks[blocksOffset++];
+ block16 = __bswap_64(block16);
+ values[valuesOffset++] = (int) (((block15 & 16777215L) << 1) | (block16 >> 63));
+ values[valuesOffset++] = (int) ((block16 >> 38) & 33554431L);
+ values[valuesOffset++] = (int) ((block16 >> 13) & 33554431L);
+ unsigned long block17 = blocks[blocksOffset++];
+ block17 = __bswap_64(block17);
+ values[valuesOffset++] = (int) (((block16 & 8191L) << 12) | (block17 >> 52));
+ values[valuesOffset++] = (int) ((block17 >> 27) & 33554431L);
+ values[valuesOffset++] = (int) ((block17 >> 2) & 33554431L);
+ unsigned long block18 = blocks[blocksOffset++];
+ block18 = __bswap_64(block18);
+ values[valuesOffset++] = (int) (((block17 & 3L) << 23) | (block18 >> 41));
+ values[valuesOffset++] = (int) ((block18 >> 16) & 33554431L);
+ unsigned long block19 = blocks[blocksOffset++];
+ block19 = __bswap_64(block19);
+ values[valuesOffset++] = (int) (((block18 & 65535L) << 9) | (block19 >> 55));
+ values[valuesOffset++] = (int) ((block19 >> 30) & 33554431L);
+ values[valuesOffset++] = (int) ((block19 >> 5) & 33554431L);
+ unsigned long block20 = blocks[blocksOffset++];
+ block20 = __bswap_64(block20);
+ values[valuesOffset++] = (int) (((block19 & 31L) << 20) | (block20 >> 44));
+ values[valuesOffset++] = (int) ((block20 >> 19) & 33554431L);
+ unsigned long block21 = blocks[blocksOffset++];
+ block21 = __bswap_64(block21);
+ values[valuesOffset++] = (int) (((block20 & 524287L) << 6) | (block21 >> 58));
+ values[valuesOffset++] = (int) ((block21 >> 33) & 33554431L);
+ values[valuesOffset++] = (int) ((block21 >> 8) & 33554431L);
+ unsigned long block22 = blocks[blocksOffset++];
+ block22 = __bswap_64(block22);
+ values[valuesOffset++] = (int) (((block21 & 255L) << 17) | (block22 >> 47));
+ values[valuesOffset++] = (int) ((block22 >> 22) & 33554431L);
+ unsigned long block23 = blocks[blocksOffset++];
+ block23 = __bswap_64(block23);
+ values[valuesOffset++] = (int) (((block22 & 4194303L) << 3) | (block23 >> 61));
+ values[valuesOffset++] = (int) ((block23 >> 36) & 33554431L);
+ values[valuesOffset++] = (int) ((block23 >> 11) & 33554431L);
+ unsigned long block24 = blocks[blocksOffset++];
+ block24 = __bswap_64(block24);
+ values[valuesOffset++] = (int) (((block23 & 2047L) << 14) | (block24 >> 50));
+ values[valuesOffset++] = (int) ((block24 >> 25) & 33554431L);
+ values[valuesOffset++] = (int) (block24 & 33554431L);
+ }
+}
+
+static void decode26(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 4; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 38);
+ values[valuesOffset++] = (int) ((block0 >> 12) & 67108863L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 4095L) << 14) | (block1 >> 50));
+ values[valuesOffset++] = (int) ((block1 >> 24) & 67108863L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 16777215L) << 2) | (block2 >> 62));
+ values[valuesOffset++] = (int) ((block2 >> 36) & 67108863L);
+ values[valuesOffset++] = (int) ((block2 >> 10) & 67108863L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 1023L) << 16) | (block3 >> 48));
+ values[valuesOffset++] = (int) ((block3 >> 22) & 67108863L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 4194303L) << 4) | (block4 >> 60));
+ values[valuesOffset++] = (int) ((block4 >> 34) & 67108863L);
+ values[valuesOffset++] = (int) ((block4 >> 8) & 67108863L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 255L) << 18) | (block5 >> 46));
+ values[valuesOffset++] = (int) ((block5 >> 20) & 67108863L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 1048575L) << 6) | (block6 >> 58));
+ values[valuesOffset++] = (int) ((block6 >> 32) & 67108863L);
+ values[valuesOffset++] = (int) ((block6 >> 6) & 67108863L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 63L) << 20) | (block7 >> 44));
+ values[valuesOffset++] = (int) ((block7 >> 18) & 67108863L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 262143L) << 8) | (block8 >> 56));
+ values[valuesOffset++] = (int) ((block8 >> 30) & 67108863L);
+ values[valuesOffset++] = (int) ((block8 >> 4) & 67108863L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 15L) << 22) | (block9 >> 42));
+ values[valuesOffset++] = (int) ((block9 >> 16) & 67108863L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 65535L) << 10) | (block10 >> 54));
+ values[valuesOffset++] = (int) ((block10 >> 28) & 67108863L);
+ values[valuesOffset++] = (int) ((block10 >> 2) & 67108863L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 3L) << 24) | (block11 >> 40));
+ values[valuesOffset++] = (int) ((block11 >> 14) & 67108863L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 16383L) << 12) | (block12 >> 52));
+ values[valuesOffset++] = (int) ((block12 >> 26) & 67108863L);
+ values[valuesOffset++] = (int) (block12 & 67108863L);
+ }
+}
+
+static void decode27(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 37);
+ values[valuesOffset++] = (int) ((block0 >> 10) & 134217727L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 1023L) << 17) | (block1 >> 47));
+ values[valuesOffset++] = (int) ((block1 >> 20) & 134217727L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 1048575L) << 7) | (block2 >> 57));
+ values[valuesOffset++] = (int) ((block2 >> 30) & 134217727L);
+ values[valuesOffset++] = (int) ((block2 >> 3) & 134217727L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 7L) << 24) | (block3 >> 40));
+ values[valuesOffset++] = (int) ((block3 >> 13) & 134217727L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 8191L) << 14) | (block4 >> 50));
+ values[valuesOffset++] = (int) ((block4 >> 23) & 134217727L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 8388607L) << 4) | (block5 >> 60));
+ values[valuesOffset++] = (int) ((block5 >> 33) & 134217727L);
+ values[valuesOffset++] = (int) ((block5 >> 6) & 134217727L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 63L) << 21) | (block6 >> 43));
+ values[valuesOffset++] = (int) ((block6 >> 16) & 134217727L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 65535L) << 11) | (block7 >> 53));
+ values[valuesOffset++] = (int) ((block7 >> 26) & 134217727L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 67108863L) << 1) | (block8 >> 63));
+ values[valuesOffset++] = (int) ((block8 >> 36) & 134217727L);
+ values[valuesOffset++] = (int) ((block8 >> 9) & 134217727L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 511L) << 18) | (block9 >> 46));
+ values[valuesOffset++] = (int) ((block9 >> 19) & 134217727L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 524287L) << 8) | (block10 >> 56));
+ values[valuesOffset++] = (int) ((block10 >> 29) & 134217727L);
+ values[valuesOffset++] = (int) ((block10 >> 2) & 134217727L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 3L) << 25) | (block11 >> 39));
+ values[valuesOffset++] = (int) ((block11 >> 12) & 134217727L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 4095L) << 15) | (block12 >> 49));
+ values[valuesOffset++] = (int) ((block12 >> 22) & 134217727L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 4194303L) << 5) | (block13 >> 59));
+ values[valuesOffset++] = (int) ((block13 >> 32) & 134217727L);
+ values[valuesOffset++] = (int) ((block13 >> 5) & 134217727L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 31L) << 22) | (block14 >> 42));
+ values[valuesOffset++] = (int) ((block14 >> 15) & 134217727L);
+ unsigned long block15 = blocks[blocksOffset++];
+ block15 = __bswap_64(block15);
+ values[valuesOffset++] = (int) (((block14 & 32767L) << 12) | (block15 >> 52));
+ values[valuesOffset++] = (int) ((block15 >> 25) & 134217727L);
+ unsigned long block16 = blocks[blocksOffset++];
+ block16 = __bswap_64(block16);
+ values[valuesOffset++] = (int) (((block15 & 33554431L) << 2) | (block16 >> 62));
+ values[valuesOffset++] = (int) ((block16 >> 35) & 134217727L);
+ values[valuesOffset++] = (int) ((block16 >> 8) & 134217727L);
+ unsigned long block17 = blocks[blocksOffset++];
+ block17 = __bswap_64(block17);
+ values[valuesOffset++] = (int) (((block16 & 255L) << 19) | (block17 >> 45));
+ values[valuesOffset++] = (int) ((block17 >> 18) & 134217727L);
+ unsigned long block18 = blocks[blocksOffset++];
+ block18 = __bswap_64(block18);
+ values[valuesOffset++] = (int) (((block17 & 262143L) << 9) | (block18 >> 55));
+ values[valuesOffset++] = (int) ((block18 >> 28) & 134217727L);
+ values[valuesOffset++] = (int) ((block18 >> 1) & 134217727L);
+ unsigned long block19 = blocks[blocksOffset++];
+ block19 = __bswap_64(block19);
+ values[valuesOffset++] = (int) (((block18 & 1L) << 26) | (block19 >> 38));
+ values[valuesOffset++] = (int) ((block19 >> 11) & 134217727L);
+ unsigned long block20 = blocks[blocksOffset++];
+ block20 = __bswap_64(block20);
+ values[valuesOffset++] = (int) (((block19 & 2047L) << 16) | (block20 >> 48));
+ values[valuesOffset++] = (int) ((block20 >> 21) & 134217727L);
+ unsigned long block21 = blocks[blocksOffset++];
+ block21 = __bswap_64(block21);
+ values[valuesOffset++] = (int) (((block20 & 2097151L) << 6) | (block21 >> 58));
+ values[valuesOffset++] = (int) ((block21 >> 31) & 134217727L);
+ values[valuesOffset++] = (int) ((block21 >> 4) & 134217727L);
+ unsigned long block22 = blocks[blocksOffset++];
+ block22 = __bswap_64(block22);
+ values[valuesOffset++] = (int) (((block21 & 15L) << 23) | (block22 >> 41));
+ values[valuesOffset++] = (int) ((block22 >> 14) & 134217727L);
+ unsigned long block23 = blocks[blocksOffset++];
+ block23 = __bswap_64(block23);
+ values[valuesOffset++] = (int) (((block22 & 16383L) << 13) | (block23 >> 51));
+ values[valuesOffset++] = (int) ((block23 >> 24) & 134217727L);
+ unsigned long block24 = blocks[blocksOffset++];
+ block24 = __bswap_64(block24);
+ values[valuesOffset++] = (int) (((block23 & 16777215L) << 3) | (block24 >> 61));
+ values[valuesOffset++] = (int) ((block24 >> 34) & 134217727L);
+ values[valuesOffset++] = (int) ((block24 >> 7) & 134217727L);
+ unsigned long block25 = blocks[blocksOffset++];
+ block25 = __bswap_64(block25);
+ values[valuesOffset++] = (int) (((block24 & 127L) << 20) | (block25 >> 44));
+ values[valuesOffset++] = (int) ((block25 >> 17) & 134217727L);
+ unsigned long block26 = blocks[blocksOffset++];
+ block26 = __bswap_64(block26);
+ values[valuesOffset++] = (int) (((block25 & 131071L) << 10) | (block26 >> 54));
+ values[valuesOffset++] = (int) ((block26 >> 27) & 134217727L);
+ values[valuesOffset++] = (int) (block26 & 134217727L);
+ }
+}
+
+static void decode28(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 8; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 36);
+ values[valuesOffset++] = (int) ((block0 >> 8) & 268435455L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 255L) << 20) | (block1 >> 44));
+ values[valuesOffset++] = (int) ((block1 >> 16) & 268435455L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 65535L) << 12) | (block2 >> 52));
+ values[valuesOffset++] = (int) ((block2 >> 24) & 268435455L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 16777215L) << 4) | (block3 >> 60));
+ values[valuesOffset++] = (int) ((block3 >> 32) & 268435455L);
+ values[valuesOffset++] = (int) ((block3 >> 4) & 268435455L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 15L) << 24) | (block4 >> 40));
+ values[valuesOffset++] = (int) ((block4 >> 12) & 268435455L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 4095L) << 16) | (block5 >> 48));
+ values[valuesOffset++] = (int) ((block5 >> 20) & 268435455L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 1048575L) << 8) | (block6 >> 56));
+ values[valuesOffset++] = (int) ((block6 >> 28) & 268435455L);
+ values[valuesOffset++] = (int) (block6 & 268435455L);
+ }
+}
+
+static void decode29(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 35);
+ values[valuesOffset++] = (int) ((block0 >> 6) & 536870911L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 63L) << 23) | (block1 >> 41));
+ values[valuesOffset++] = (int) ((block1 >> 12) & 536870911L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 4095L) << 17) | (block2 >> 47));
+ values[valuesOffset++] = (int) ((block2 >> 18) & 536870911L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 262143L) << 11) | (block3 >> 53));
+ values[valuesOffset++] = (int) ((block3 >> 24) & 536870911L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 16777215L) << 5) | (block4 >> 59));
+ values[valuesOffset++] = (int) ((block4 >> 30) & 536870911L);
+ values[valuesOffset++] = (int) ((block4 >> 1) & 536870911L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 1L) << 28) | (block5 >> 36));
+ values[valuesOffset++] = (int) ((block5 >> 7) & 536870911L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 127L) << 22) | (block6 >> 42));
+ values[valuesOffset++] = (int) ((block6 >> 13) & 536870911L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 8191L) << 16) | (block7 >> 48));
+ values[valuesOffset++] = (int) ((block7 >> 19) & 536870911L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 524287L) << 10) | (block8 >> 54));
+ values[valuesOffset++] = (int) ((block8 >> 25) & 536870911L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 33554431L) << 4) | (block9 >> 60));
+ values[valuesOffset++] = (int) ((block9 >> 31) & 536870911L);
+ values[valuesOffset++] = (int) ((block9 >> 2) & 536870911L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 3L) << 27) | (block10 >> 37));
+ values[valuesOffset++] = (int) ((block10 >> 8) & 536870911L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 255L) << 21) | (block11 >> 43));
+ values[valuesOffset++] = (int) ((block11 >> 14) & 536870911L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 16383L) << 15) | (block12 >> 49));
+ values[valuesOffset++] = (int) ((block12 >> 20) & 536870911L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 1048575L) << 9) | (block13 >> 55));
+ values[valuesOffset++] = (int) ((block13 >> 26) & 536870911L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 67108863L) << 3) | (block14 >> 61));
+ values[valuesOffset++] = (int) ((block14 >> 32) & 536870911L);
+ values[valuesOffset++] = (int) ((block14 >> 3) & 536870911L);
+ unsigned long block15 = blocks[blocksOffset++];
+ block15 = __bswap_64(block15);
+ values[valuesOffset++] = (int) (((block14 & 7L) << 26) | (block15 >> 38));
+ values[valuesOffset++] = (int) ((block15 >> 9) & 536870911L);
+ unsigned long block16 = blocks[blocksOffset++];
+ block16 = __bswap_64(block16);
+ values[valuesOffset++] = (int) (((block15 & 511L) << 20) | (block16 >> 44));
+ values[valuesOffset++] = (int) ((block16 >> 15) & 536870911L);
+ unsigned long block17 = blocks[blocksOffset++];
+ block17 = __bswap_64(block17);
+ values[valuesOffset++] = (int) (((block16 & 32767L) << 14) | (block17 >> 50));
+ values[valuesOffset++] = (int) ((block17 >> 21) & 536870911L);
+ unsigned long block18 = blocks[blocksOffset++];
+ block18 = __bswap_64(block18);
+ values[valuesOffset++] = (int) (((block17 & 2097151L) << 8) | (block18 >> 56));
+ values[valuesOffset++] = (int) ((block18 >> 27) & 536870911L);
+ unsigned long block19 = blocks[blocksOffset++];
+ block19 = __bswap_64(block19);
+ values[valuesOffset++] = (int) (((block18 & 134217727L) << 2) | (block19 >> 62));
+ values[valuesOffset++] = (int) ((block19 >> 33) & 536870911L);
+ values[valuesOffset++] = (int) ((block19 >> 4) & 536870911L);
+ unsigned long block20 = blocks[blocksOffset++];
+ block20 = __bswap_64(block20);
+ values[valuesOffset++] = (int) (((block19 & 15L) << 25) | (block20 >> 39));
+ values[valuesOffset++] = (int) ((block20 >> 10) & 536870911L);
+ unsigned long block21 = blocks[blocksOffset++];
+ block21 = __bswap_64(block21);
+ values[valuesOffset++] = (int) (((block20 & 1023L) << 19) | (block21 >> 45));
+ values[valuesOffset++] = (int) ((block21 >> 16) & 536870911L);
+ unsigned long block22 = blocks[blocksOffset++];
+ block22 = __bswap_64(block22);
+ values[valuesOffset++] = (int) (((block21 & 65535L) << 13) | (block22 >> 51));
+ values[valuesOffset++] = (int) ((block22 >> 22) & 536870911L);
+ unsigned long block23 = blocks[blocksOffset++];
+ block23 = __bswap_64(block23);
+ values[valuesOffset++] = (int) (((block22 & 4194303L) << 7) | (block23 >> 57));
+ values[valuesOffset++] = (int) ((block23 >> 28) & 536870911L);
+ unsigned long block24 = blocks[blocksOffset++];
+ block24 = __bswap_64(block24);
+ values[valuesOffset++] = (int) (((block23 & 268435455L) << 1) | (block24 >> 63));
+ values[valuesOffset++] = (int) ((block24 >> 34) & 536870911L);
+ values[valuesOffset++] = (int) ((block24 >> 5) & 536870911L);
+ unsigned long block25 = blocks[blocksOffset++];
+ block25 = __bswap_64(block25);
+ values[valuesOffset++] = (int) (((block24 & 31L) << 24) | (block25 >> 40));
+ values[valuesOffset++] = (int) ((block25 >> 11) & 536870911L);
+ unsigned long block26 = blocks[blocksOffset++];
+ block26 = __bswap_64(block26);
+ values[valuesOffset++] = (int) (((block25 & 2047L) << 18) | (block26 >> 46));
+ values[valuesOffset++] = (int) ((block26 >> 17) & 536870911L);
+ unsigned long block27 = blocks[blocksOffset++];
+ block27 = __bswap_64(block27);
+ values[valuesOffset++] = (int) (((block26 & 131071L) << 12) | (block27 >> 52));
+ values[valuesOffset++] = (int) ((block27 >> 23) & 536870911L);
+ unsigned long block28 = blocks[blocksOffset++];
+ block28 = __bswap_64(block28);
+ values[valuesOffset++] = (int) (((block27 & 8388607L) << 6) | (block28 >> 58));
+ values[valuesOffset++] = (int) ((block28 >> 29) & 536870911L);
+ values[valuesOffset++] = (int) (block28 & 536870911L);
+ }
+}
+
+static void decode30(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 4; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 34);
+ values[valuesOffset++] = (int) ((block0 >> 4) & 1073741823L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 15L) << 26) | (block1 >> 38));
+ values[valuesOffset++] = (int) ((block1 >> 8) & 1073741823L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 255L) << 22) | (block2 >> 42));
+ values[valuesOffset++] = (int) ((block2 >> 12) & 1073741823L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 4095L) << 18) | (block3 >> 46));
+ values[valuesOffset++] = (int) ((block3 >> 16) & 1073741823L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 65535L) << 14) | (block4 >> 50));
+ values[valuesOffset++] = (int) ((block4 >> 20) & 1073741823L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 1048575L) << 10) | (block5 >> 54));
+ values[valuesOffset++] = (int) ((block5 >> 24) & 1073741823L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 16777215L) << 6) | (block6 >> 58));
+ values[valuesOffset++] = (int) ((block6 >> 28) & 1073741823L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 268435455L) << 2) | (block7 >> 62));
+ values[valuesOffset++] = (int) ((block7 >> 32) & 1073741823L);
+ values[valuesOffset++] = (int) ((block7 >> 2) & 1073741823L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 3L) << 28) | (block8 >> 36));
+ values[valuesOffset++] = (int) ((block8 >> 6) & 1073741823L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 63L) << 24) | (block9 >> 40));
+ values[valuesOffset++] = (int) ((block9 >> 10) & 1073741823L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 1023L) << 20) | (block10 >> 44));
+ values[valuesOffset++] = (int) ((block10 >> 14) & 1073741823L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 16383L) << 16) | (block11 >> 48));
+ values[valuesOffset++] = (int) ((block11 >> 18) & 1073741823L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 262143L) << 12) | (block12 >> 52));
+ values[valuesOffset++] = (int) ((block12 >> 22) & 1073741823L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 4194303L) << 8) | (block13 >> 56));
+ values[valuesOffset++] = (int) ((block13 >> 26) & 1073741823L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 67108863L) << 4) | (block14 >> 60));
+ values[valuesOffset++] = (int) ((block14 >> 30) & 1073741823L);
+ values[valuesOffset++] = (int) (block14 & 1073741823L);
+ }
+}
+
+static void decode31(unsigned long *blocks, unsigned int *values) {
+ int blocksOffset = 0;
+ int valuesOffset = 0;
+ for (int i = 0; i < 2; ++i) {
+ unsigned long block0 = blocks[blocksOffset++];
+ block0 = __bswap_64(block0);
+ values[valuesOffset++] = (int) (block0 >> 33);
+ values[valuesOffset++] = (int) ((block0 >> 2) & 2147483647L);
+ unsigned long block1 = blocks[blocksOffset++];
+ block1 = __bswap_64(block1);
+ values[valuesOffset++] = (int) (((block0 & 3L) << 29) | (block1 >> 35));
+ values[valuesOffset++] = (int) ((block1 >> 4) & 2147483647L);
+ unsigned long block2 = blocks[blocksOffset++];
+ block2 = __bswap_64(block2);
+ values[valuesOffset++] = (int) (((block1 & 15L) << 27) | (block2 >> 37));
+ values[valuesOffset++] = (int) ((block2 >> 6) & 2147483647L);
+ unsigned long block3 = blocks[blocksOffset++];
+ block3 = __bswap_64(block3);
+ values[valuesOffset++] = (int) (((block2 & 63L) << 25) | (block3 >> 39));
+ values[valuesOffset++] = (int) ((block3 >> 8) & 2147483647L);
+ unsigned long block4 = blocks[blocksOffset++];
+ block4 = __bswap_64(block4);
+ values[valuesOffset++] = (int) (((block3 & 255L) << 23) | (block4 >> 41));
+ values[valuesOffset++] = (int) ((block4 >> 10) & 2147483647L);
+ unsigned long block5 = blocks[blocksOffset++];
+ block5 = __bswap_64(block5);
+ values[valuesOffset++] = (int) (((block4 & 1023L) << 21) | (block5 >> 43));
+ values[valuesOffset++] = (int) ((block5 >> 12) & 2147483647L);
+ unsigned long block6 = blocks[blocksOffset++];
+ block6 = __bswap_64(block6);
+ values[valuesOffset++] = (int) (((block5 & 4095L) << 19) | (block6 >> 45));
+ values[valuesOffset++] = (int) ((block6 >> 14) & 2147483647L);
+ unsigned long block7 = blocks[blocksOffset++];
+ block7 = __bswap_64(block7);
+ values[valuesOffset++] = (int) (((block6 & 16383L) << 17) | (block7 >> 47));
+ values[valuesOffset++] = (int) ((block7 >> 16) & 2147483647L);
+ unsigned long block8 = blocks[blocksOffset++];
+ block8 = __bswap_64(block8);
+ values[valuesOffset++] = (int) (((block7 & 65535L) << 15) | (block8 >> 49));
+ values[valuesOffset++] = (int) ((block8 >> 18) & 2147483647L);
+ unsigned long block9 = blocks[blocksOffset++];
+ block9 = __bswap_64(block9);
+ values[valuesOffset++] = (int) (((block8 & 262143L) << 13) | (block9 >> 51));
+ values[valuesOffset++] = (int) ((block9 >> 20) & 2147483647L);
+ unsigned long block10 = blocks[blocksOffset++];
+ block10 = __bswap_64(block10);
+ values[valuesOffset++] = (int) (((block9 & 1048575L) << 11) | (block10 >> 53));
+ values[valuesOffset++] = (int) ((block10 >> 22) & 2147483647L);
+ unsigned long block11 = blocks[blocksOffset++];
+ block11 = __bswap_64(block11);
+ values[valuesOffset++] = (int) (((block10 & 4194303L) << 9) | (block11 >> 55));
+ values[valuesOffset++] = (int) ((block11 >> 24) & 2147483647L);
+ unsigned long block12 = blocks[blocksOffset++];
+ block12 = __bswap_64(block12);
+ values[valuesOffset++] = (int) (((block11 & 16777215L) << 7) | (block12 >> 57));
+ values[valuesOffset++] = (int) ((block12 >> 26) & 2147483647L);
+ unsigned long block13 = blocks[blocksOffset++];
+ block13 = __bswap_64(block13);
+ values[valuesOffset++] = (int) (((block12 & 67108863L) << 5) | (block13 >> 59));
+ values[valuesOffset++] = (int) ((block13 >> 28) & 2147483647L);
+ unsigned long block14 = blocks[blocksOffset++];
+ block14 = __bswap_64(block14);
+ values[valuesOffset++] = (int) (((block13 & 268435455L) << 3) | (block14 >> 61));
+ values[valuesOffset++] = (int) ((block14 >> 30) & 2147483647L);
+ unsigned long block15 = blocks[blocksOffset++];
+ block15 = __bswap_64(block15);
+ values[valuesOffset++] = (int) (((block14 & 1073741823L) << 1) | (block15 >> 63));
+ values[valuesOffset++] = (int) ((block15 >> 32) & 2147483647L);
+ values[valuesOffset++] = (int) ((block15 >> 1) & 2147483647L);
+ unsigned long block16 = blocks[blocksOffset++];
+ block16 = __bswap_64(block16);
+ values[valuesOffset++] = (int) (((block15 & 1L) << 30) | (block16 >> 34));
+ values[valuesOffset++] = (int) ((block16 >> 3) & 2147483647L);
+ unsigned long block17 = blocks[blocksOffset++];
+ block17 = __bswap_64(block17);
+ values[valuesOffset++] = (int) (((block16 & 7L) << 28) | (block17 >> 36));
+ values[valuesOffset++] = (int) ((block17 >> 5) & 2147483647L);
+ unsigned long block18 = blocks[blocksOffset++];
+ block18 = __bswap_64(block18);
+ values[valuesOffset++] = (int) (((block17 & 31L) << 26) | (block18 >> 38));
+ values[valuesOffset++] = (int) ((block18 >> 7) & 2147483647L);
+ unsigned long block19 = blocks[blocksOffset++];
+ block19 = __bswap_64(block19);
+ values[valuesOffset++] = (int) (((block18 & 127L) << 24) | (block19 >> 40));
+ values[valuesOffset++] = (int) ((block19 >> 9) & 2147483647L);
+ unsigned long block20 = blocks[blocksOffset++];
+ block20 = __bswap_64(block20);
+ values[valuesOffset++] = (int) (((block19 & 511L) << 22) | (block20 >> 42));
+ values[valuesOffset++] = (int) ((block20 >> 11) & 2147483647L);
+ unsigned long block21 = blocks[blocksOffset++];
+ block21 = __bswap_64(block21);
+ values[valuesOffset++] = (int) (((block20 & 2047L) << 20) | (block21 >> 44));
+ values[valuesOffset++] = (int) ((block21 >> 13) & 2147483647L);
+ unsigned long block22 = blocks[blocksOffset++];
+ block22 = __bswap_64(block22);
+ values[valuesOffset++] = (int) (((block21 & 8191L) << 18) | (block22 >> 46));
+ values[valuesOffset++] = (int) ((block22 >> 15) & 2147483647L);
+ unsigned long block23 = blocks[blocksOffset++];
+ block23 = __bswap_64(block23);
+ values[valuesOffset++] = (int) (((block22 & 32767L) << 16) | (block23 >> 48));
+ values[valuesOffset++] = (int) ((block23 >> 17) & 2147483647L);
+ unsigned long block24 = blocks[blocksOffset++];
+ block24 = __bswap_64(block24);
+ values[valuesOffset++] = (int) (((block23 & 131071L) << 14) | (block24 >> 50));
+ values[valuesOffset++] = (int) ((block24 >> 19) & 2147483647L);
+ unsigned long block25 = blocks[blocksOffset++];
+ block25 = __bswap_64(block25);
+ values[valuesOffset++] = (int) (((block24 & 524287L) << 12) | (block25 >> 52));
+ values[valuesOffset++] = (int) ((block25 >> 21) & 2147483647L);
+ unsigned long block26 = blocks[blocksOffset++];
+ block26 = __bswap_64(block26);
+ values[valuesOffset++] = (int) (((block25 & 2097151L) << 10) | (block26 >> 54));
+ values[valuesOffset++] = (int) ((block26 >> 23) & 2147483647L);
+ unsigned long block27 = blocks[blocksOffset++];
+ block27 = __bswap_64(block27);
+ values[valuesOffset++] = (int) (((block26 & 8388607L) << 8) | (block27 >> 56));
+ values[valuesOffset++] = (int) ((block27 >> 25) & 2147483647L);
+ unsigned long block28 = blocks[blocksOffset++];
+ block28 = __bswap_64(block28);
+ values[valuesOffset++] = (int) (((block27 & 33554431L) << 6) | (block28 >> 58));
+ values[valuesOffset++] = (int) ((block28 >> 27) & 2147483647L);
+ unsigned long block29 = blocks[blocksOffset++];
+ block29 = __bswap_64(block29);
+ values[valuesOffset++] = (int) (((block28 & 134217727L) << 4) | (block29 >> 60));
+ values[valuesOffset++] = (int) ((block29 >> 29) & 2147483647L);
+ unsigned long block30 = blocks[blocksOffset++];
+ block30 = __bswap_64(block30);
+ values[valuesOffset++] = (int) (((block29 & 536870911L) << 2) | (block30 >> 62));
+ values[valuesOffset++] = (int) ((block30 >> 31) & 2147483647L);
+ values[valuesOffset++] = (int) (block30 & 2147483647L);
+ }
+}
+
+
+// switch statement is a bit faster:
+/*
+typedef void (*blockDecoder)(unsigned long *, unsigned int *);
+
+static blockDecoder blockDecoders[32] = {0,
+ decodeSingleBlock1,
+ decodeSingleBlock2,
+ decode3,
+ decodeSingleBlock4,
+ decode5,
+ decode6,
+ decode7,
+ decode8,
+ decode9,
+ decode10,
+ decode11,
+ decode12,
+ decode13,
+ decode14,
+ decode15,
+ decode16,
+ decode17,
+ decode18,
+ decode19,
+ decode20,
+ decode21,
+ decode22,
+ decode23,
+ decode24,
+ decode25,
+ decode26,
+ decode27,
+ decode28,
+ decode29,
+ decode30,
+ decode31};
+*/
+
+static void readPackedBlock(unsigned long *longBuffer, PostingsState *sub, unsigned int *dest) {
+ unsigned char bitsPerValue = readByte(sub);
+ //printf("\nreadPackedBlock bpv=%d\n", bitsPerValue);
+ if (bitsPerValue == 0) {
+ // All values equal
+ unsigned int v = readVInt(sub);
+ for(int i=0;i<BLOCK_SIZE;i++) {
+ dest[i] = v;
+ }
+ } else {
+ int numBytes = bitsPerValue*16;
+ //printf("\n %d bytes @ p=%d\n", numBytes, (int) (sub->p - globalAddress));
+
+ // NOTE: this hurts a bit, i think because of having to
+ // skip wasted bytes:
+ // Align to 8 bytes:
+ /*
+ long x = (long) sub->p;
+ x = (x+7) & ~7;
+ sub->p = (unsigned char *) x;
+ */
+
+ // NOTE: this hurts a bit, but if we want to use aligned
+ // SIMD it will be necessary unless we fix PF to write
+ // all bytes aligned to 16 byte boundaries:
+ //memcpy(longBuffer, sub->p, numBytes);
+ longBuffer = (unsigned long *) sub->p;
+ sub->p += numBytes;
+
+ // NOTE: Block PF uses PACKED_SINGLE_BLOCK for
+ // bpv=1,2,4, else "ordinary" packed:
+
+ // switch statement is a bit faster:
+ //blockDecoders[bitsPerValue](longBuffer, dest);
+
+ switch(bitsPerValue) {
+ case 1:
+ decodeSingleBlock1(longBuffer, dest);
+ break;
+ case 2:
+ decodeSingleBlock2(longBuffer, dest);
+ break;
+ case 3:
+ decode3(longBuffer, dest);
+ break;
+ case 4:
+ decodeSingleBlock4(longBuffer, dest);
+ break;
+ case 5:
+ decode5(longBuffer, dest);
+ break;
+ case 6:
+ decode6(longBuffer, dest);
+ break;
+ case 7:
+ decode7(longBuffer, dest);
+ break;
+ case 8:
+ decode8(longBuffer, dest);
+ break;
+ case 9:
+ decode9(longBuffer, dest);
+ break;
+ case 10:
+ decode10(longBuffer, dest);
+ break;
+ case 11:
+ decode11(longBuffer, dest);
+ break;
+ case 12:
+ decode12(longBuffer, dest);
+ break;
+ case 13:
+ decode13(longBuffer, dest);
+ break;
+ case 14:
+ decode14(longBuffer, dest);
+ break;
+ case 15:
+ decode15(longBuffer, dest);
+ break;
+ case 16:
+ decode16(longBuffer, dest);
+ break;
+ case 17:
+ decode17(longBuffer, dest);
+ break;
+ case 18:
+ decode18(longBuffer, dest);
+ break;
+ case 19:
+ decode19(longBuffer, dest);
+ break;
+ case 20:
+ decode20(longBuffer, dest);
+ break;
+ case 21:
+ decode21(longBuffer, dest);
+ break;
+ case 22:
+ decode22(longBuffer, dest);
+ break;
+ case 23:
+ decode23(longBuffer, dest);
+ break;
+ case 24:
+ decode24(longBuffer, dest);
+ break;
+ case 25:
+ decode25(longBuffer, dest);
+ break;
+ case 26:
+ decode26(longBuffer, dest);
+ break;
+ case 27:
+ decode27(longBuffer, dest);
+ break;
+ case 28:
+ decode28(longBuffer, dest);
+ break;
+ case 29:
+ decode29(longBuffer, dest);
+ break;
+ case 30:
+ decode30(longBuffer, dest);
+ break;
+ case 31:
+ decode31(longBuffer, dest);
+ break;
+ }
+ }
+}
+// END AUTOGEN CODE (gen_Packed.py)
+
+static void readVIntBlock(PostingsState *sub) {
+ //printf(" readVIntBlock: %d docs\n", sub->docsLeft);
+ for(int i=0;i<sub->docsLeft;i++) {
+ unsigned int code = readVInt(sub);
+ sub->docDeltas[i] = code >> 1;
+ if ((code & 1) != 0) {
+ sub->freqs[i] = 1;
+ } else {
+ sub->freqs[i] = readVInt(sub);
+ }
+ //printf(" docDeltas[%d] = %d\n", i, sub->docDeltas[i]);
+ //printf(" freqs[%d] = %d\n", i, sub->freqs[i]);
+ }
+}
+
+static void nextBlock(unsigned long *longBuffer, PostingsState* sub) {
+ sub->blockLastRead = -1;
+ if (sub->docsLeft >= BLOCK_SIZE) {
+ //printf(" nextBlock: packed\n");
+ readPackedBlock(longBuffer, sub, sub->docDeltas);
+ readPackedBlock(longBuffer, sub, sub->freqs);
+ sub->docsLeft -= BLOCK_SIZE;
+ // nocommit redundant?: only needs to be done up front?
+ sub->blockEnd = BLOCK_SIZE-1;
+ } else {
+ //printf(" nextBlock: vInt\n");
+ sub->blockEnd = sub->docsLeft-1;
+ readVIntBlock(sub);
+ sub->docsLeft = 0;
+ }
+}
+
+/*
+static void nextDoc(unsigned long *longBuffer, PostingsState *sub, unsigned char *liveDocs) {
+ while (true) {
+ if (sub->blockNextRead == sub->blockEnd-1) {
+ if (sub->docsLeft == 0) {
+ sub->nextDocID = NO_MORE_DOCS;
+ return;
+ } else {
+ nextBlock(longBuffer, sub);
+ }
+ }
+ sub->nextDocID += sub->docDeltas[sub->blockNextRead];
+ sub->nextFreq = sub->freqs[sub->blockNextRead];
+ sub->blockNextRead++;
+ if (liveDocs == 0 || isSet(liveDocs, sub->nextDocID)) {
+ return;
+ }
+ }
+}
+*/
+
+static bool
+lessThan(int docID1, float score1, int docID2, float score2) {
+ if (score1 < score2) {
+ return true;
+ } else if (score1 > score2) {
+ return false;
+ } else {
+ if (docID1 > docID2) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+static void
+downHeap(int heapSize, int *topDocIDs, float *topScores) {
+ int i = 1;
+ // save top node
+ int savDocID = topDocIDs[i];
+ float savScore = topScores[i];
+ int j = i << 1; // find smaller child
+ int k = j + 1;
+ if (k <= heapSize && lessThan(topDocIDs[k], topScores[k], topDocIDs[j], topScores[j])) {
+ j = k;
+ }
+ while (j <= heapSize && lessThan(topDocIDs[j], topScores[j], savDocID, savScore)) {
+ // shift up child
+ topDocIDs[i] = topDocIDs[j];
+ topScores[i] = topScores[j];
+ i = j;
+ j = i << 1;
+ k = j + 1;
+ if (k <= heapSize && lessThan(topDocIDs[k], topScores[k], topDocIDs[j], topScores[j])) {
+ j = k;
+ }
+ }
+ // install saved node
+ topDocIDs[i] = savDocID;
+ topScores[i] = savScore;
+}
+
+extern "C" JNIEXPORT jint JNICALL
+Java_org_apache_lucene_search_NativeSearch_searchSegment
+ (JNIEnv *env,
+ jclass cl,
+
+ // PQ holding top hits so far, pre-filled with sentinel
+ // values:
+ jintArray jtopDocIDs,
+ jfloatArray jtopScores,
+
+ // Current segment's maxDoc
+ jint maxDoc,
+
+ // Current segment's docBase
+ jint docBase,
+
+ // Current segment's liveDocs, or null:
+ jbyteArray jliveDocBytes,
+
+ // weightValue from each TermWeight:
+ jfloatArray jtermWeights,
+
+ // Norms for the field (all TermQuery must be against a single field):
+ jbyteArray jnorms,
+
+ // nocommit silly to pass this once for each segment:
+ // Cache, mapping byte norm -> float
+ jfloatArray jnormTable,
+
+ // Coord factors from BQ:
+ jfloatArray jcoordFactors,
+
+ // If the term has only one docID in this segment (it was
+ // "pulsed") then its set here, else -1:
+ jintArray jsingletonDocIDs,
+
+ // docFreq of each term
+ jintArray jdocFreqs,
+
+ // Offset in the .doc file where this term's docs+freqs begin:
+ jlongArray jdocTermStartFPs,
+
+ // Address in memory where .doc file is mapped:
+ jlong docFileAddress)
+{
+ unsigned long __attribute__ ((aligned(16))) longBuffer[64];
+
+ //printf("START search\n"); fflush(stdout);
+
+ float *scores = (float *) malloc(CHUNK * sizeof(float));
+ unsigned int *coords = (unsigned int *) malloc(CHUNK * sizeof(int));
+ int *docIDs = (int *) malloc(CHUNK * sizeof(int));
+
+ for(int i=0;i<CHUNK;i++) {
+ docIDs[i] = -1;
+ }
+
+ int numScorers = env->GetArrayLength(jdocFreqs);
+
+ int topN = env->GetArrayLength(jtopDocIDs) - 1;
+ //printf("topN=%d\n", topN);
+
+ PostingsState *subs = (PostingsState *) malloc(numScorers*sizeof(PostingsState));
+
+ int *singletonDocIDs = env->GetIntArrayElements(jsingletonDocIDs, 0);
+ long *docTermStartFPs = env->GetLongArrayElements(jdocTermStartFPs, 0);
+ int *docFreqs = env->GetIntArrayElements(jdocFreqs, 0);
+ float *termWeights = (float *) env->GetFloatArrayElements(jtermWeights, 0);
+ float *coordFactors = (float *) env->GetFloatArrayElements(jcoordFactors, 0);
+
+ unsigned char isCopy = 0;
+ unsigned char *liveDocBytes;
+ if (jliveDocBytes == 0) {
+ liveDocBytes = 0;
+ } else {
+ liveDocBytes = (unsigned char *) env->GetPrimitiveArrayCritical(jliveDocBytes, &isCopy);
+ //printf("liveDocs isCopy=%d\n", isCopy);fflush(stdout);
+ }
+
+ isCopy = 0;
+ unsigned char* norms = (unsigned char *) env->GetPrimitiveArrayCritical(jnorms, &isCopy);
+ //printf("norms isCopy=%d\n", isCopy);fflush(stdout);
+
+ isCopy = 0;
+ float *normTable = (float *) env->GetPrimitiveArrayCritical(jnormTable, &isCopy);
+ //printf("normTable %lx isCopy=%d\n", normTable, isCopy);fflush(stdout);
+ unsigned int *freq1 = (unsigned int *) malloc(sizeof(int));
+ freq1[0] = 1;
+ // Init scorers:
+ for(int i=0;i<numScorers;i++) {
+ PostingsState *sub = &(subs[i]);
+ sub->id = i;
+ //printf("init scorers[%d] of %d\n", i, numScorers);
+
+ if (singletonDocIDs[i] != -1) {
+ //printf(" singleton: %d\n", singletonDocIDs[i]);
+ sub->nextDocID = singletonDocIDs[i];
+ sub->docsLeft = 0;
+ sub->blockLastRead = 0;
+ sub->blockEnd = 0;
+ sub->docDeltas = 0;
+ sub->freqs = freq1;
+ } else {
+ sub->docsLeft = docFreqs[i];
+ sub->docDeltas = (unsigned int *) malloc(2*BLOCK_SIZE*sizeof(int));
+ // Locality seemed to help here:
+ sub->freqs = sub->docDeltas + BLOCK_SIZE;
+ //printf("docFileAddress=%ld startFP=%ld\n", docFileAddress, docTermStartFPs[i]);fflush(stdout);
+ sub->p = ((unsigned char *) docFileAddress) + docTermStartFPs[i];
+ //printf(" not singleton\n");
+ nextBlock(longBuffer, sub);
+ sub->nextDocID = sub->docDeltas[0];
+ //printf("docDeltas[0]=%d\n", sub->docDeltas[0]);
+ sub->blockLastRead = 0;
+ }
+ //printf("init i=%d nextDocID=%d freq=%d blockEnd=%d singleton=%d\n", i, sub->nextDocID, sub->nextFreq, sub->blockEnd, singletonDocIDs[i]);fflush(stdout);
+ }
+
+
+ int docUpto = 0;
+
+ // PQ holding top hits:
+ int *topDocIDs = (int *) env->GetIntArrayElements(jtopDocIDs, 0);
+ float *topScores = (float *) env->GetFloatArrayElements(jtopScores, 0);
+ int *filled = (int *) malloc(CHUNK * sizeof(int));
+ int numFilled;
+ int hitCount = 0;
+ /*
+ double *sqrtCache = (double *) malloc(32*sizeof(double));
+ for(int i=1;i<32;i++) {
+ sqrtCache[i] = sqrt(i);
+ }
+ */
+
+ double **termScoreCache = (double **) malloc(numScorers*sizeof(double*));
+ for(int i=0;i<numScorers;i++) {
+ termScoreCache[i] = (double *) malloc(32*sizeof(double));
+ for(int j=0;j<32;j++) {
+ termScoreCache[i][j] = termWeights[i] * sqrt(j);
+ }
+ }
+
+ while (docUpto < maxDoc) {
+ register int endDoc = docUpto + CHUNK;
+ numFilled = 0;
+
+ // Collect first sub without if, since we know every
+ // slot will be stale:
+
+ PostingsState *sub;
+
+ register float termWeight;
+
+ register int nextDocID;
+ register unsigned int *docDeltas;
+ register unsigned int *freqs;
+
+ register int blockLastRead;
+ register int blockEnd;
+ register double *tsCache;
+
+ sub = &(subs[0]);
+
+ termWeight = termWeights[0];
+
+ nextDocID = sub->nextDocID;
+ docDeltas = sub->docDeltas;
+ freqs = sub->freqs;
+
+ blockLastRead = sub->blockLastRead;
+ blockEnd = sub->blockEnd;
+ tsCache = termScoreCache[0];
+
+ // First scorer is different because we know slot is
+ // "new" for every hit:
+ //printf("scorers[0]\n");
+ while (nextDocID < endDoc) {
+ //if (liveDocBytes == 0 || isSet(liveDocBytes, nextDocID)) {
+ //printf(" docID=%d\n", nextDocID);
+ int slot = nextDocID & MASK;
+ int freq = freqs[blockLastRead];
+ docIDs[slot] = nextDocID;
+ if (freq < 32) {
+ scores[slot] = tsCache[freq];
+ } else {
+ scores[slot] = sqrt(freq) * termWeight;
+ }
+ coords[slot] = 1;
+ filled[numFilled++] = slot;
+ //}
+
+ // Inlined nextDoc:
+ if (blockLastRead == blockEnd) {
+ if (sub->docsLeft == 0) {
+ nextDocID = NO_MORE_DOCS;
+ break;
+ } else {
+ nextBlock(longBuffer, sub);
+ blockLastRead = -1;
+ blockEnd = sub->blockEnd;
+ }
+ }
+ nextDocID += docDeltas[++blockLastRead];
+ }
+ sub->nextDocID = nextDocID;
+ sub->blockLastRead = blockLastRead;
+
+ for(int i=0;i<numScorers;i++) {
+ //printf("scorers[%d]\n", i);
+ PostingsState *sub = &(subs[i]);
+
+ termWeight = termWeights[i];
+
+ nextDocID = sub->nextDocID;
+ docDeltas = sub->docDeltas;
+ freqs = sub->freqs;
+
+ blockLastRead = sub->blockLastRead;
+ blockEnd = sub->blockEnd;
+ tsCache = termScoreCache[i];
+
+ //printf("term=%d nextDoc=%d\n", i, sub->nextDocID);
+ while (nextDocID < endDoc) {
+ //printf(" docID=%d\n", nextDocID);
+ //if (liveDocBytes == 0 || isSet(liveDocBytes, nextDocID)) {
+ int slot = nextDocID & MASK;
+ int freq = freqs[blockLastRead];
+ double score;
+ if (freq < 32) {
+ score = tsCache[freq];
+ } else {
+ score = sqrt(freq) * termWeight;
+ }
+
+ if (docIDs[slot] != nextDocID) {
+ docIDs[slot] = nextDocID;
+ scores[slot] = score;
+ coords[slot] = 1;
+ filled[numFilled++] = slot;
+ } else {
+ scores[slot] += score;
+ coords[slot]++;
+ }
+ // }
+
+ // Inlined nextDoc:
+ if (blockLastRead == blockEnd) {
+ if (sub->docsLeft == 0) {
+ nextDocID = NO_MORE_DOCS;
+ break;
+ } else {
+ nextBlock(longBuffer, sub);
+ blockLastRead = -1;
+ blockEnd = sub->blockEnd;
+ }
+ }
+ nextDocID += docDeltas[++blockLastRead];
+ }
+
+ sub->nextDocID = nextDocID;
+ sub->blockLastRead = blockLastRead;
+ }
+
+ hitCount += numFilled;
+
+ // Collect:
+ //printf("collect:\n");
+ for(int i=0;i<numFilled;i++) {
+ int slot = filled[i];
+ float score = scores[slot] * coordFactors[coords[slot]] * normTable[norms[docIDs[slot]]];
+ int docID = docBase + docIDs[slot];
+ //printf(" docBase=%d doc=%d score=%.5f coord=%d cf=%.5f\n",
+ //docBase, docID, score, coords[slot], coordFactors[coords[slot]]);
+
+ if (score > topScores[1] || (score == topScores[1] && docID < topDocIDs[1])) {
+ // Hit is competitive
+ topDocIDs[1] = docID;
+ topScores[1] = score;
+
+ downHeap(topN, topDocIDs, topScores);
+
+ //printf(" **\n");fflush(stdout);
+ }
+ }
+
+ docUpto += CHUNK;
+ }
+
+ env->ReleasePrimitiveArrayCritical(jnorms, norms, JNI_ABORT);
+ env->ReleasePrimitiveArrayCritical(jliveDocBytes, liveDocBytes, JNI_ABORT);
+ env->ReleasePrimitiveArrayCritical(jnormTable, normTable, JNI_ABORT);
+
+ env->ReleaseIntArrayElements(jsingletonDocIDs, singletonDocIDs, JNI_ABORT);
+ env->ReleaseLongArrayElements(jdocTermStartFPs, docTermStartFPs, JNI_ABORT);
+ env->ReleaseIntArrayElements(jdocFreqs, docFreqs, JNI_ABORT);
+ env->ReleaseFloatArrayElements(jtermWeights, termWeights, JNI_ABORT);
+ env->ReleaseFloatArrayElements(jcoordFactors, coordFactors, JNI_ABORT);
+
+ env->ReleaseIntArrayElements(jtopDocIDs, topDocIDs, JNI_COMMIT);
+ env->ReleaseFloatArrayElements(jtopScores, topScores, JNI_COMMIT);
+
+ for(int i=0;i<numScorers;i++) {
+ free(termScoreCache[i]);
+ }
+ free(termScoreCache);
+ free(filled);
+ free(scores);
+ free(docIDs);
+ free(coords);
+ free(freq1);
+ for(int i=0;i<numScorers;i++) {
+ PostingsState *sub = &(subs[i]);
+ if (sub->docDeltas != 0) {
+ free(sub->docDeltas);
+ }
+ }
+
+ free(subs);
+
+ return hitCount;
+}
Property changes on: lucene/misc/src/java/org/apache/lucene/search/NativeSearch.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/misc/src/java/org/apache/lucene/store/NativeMMapDirectory.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/store/NativeMMapDirectory.java (revision 0)
+++ lucene/misc/src/java/org/apache/lucene/store/NativeMMapDirectory.java (working copy)
@@ -0,0 +1,150 @@
+package org.apache.lucene.store;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.reflect.*;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+
+import sun.misc.Unsafe;
+
+public class NativeMMapDirectory extends FSDirectory {
+
+ static {
+ System.loadLibrary("NativeMMapDirectory");
+ }
+
+ private final static native long map(int fd, long fileLength);
+ private final static native void unmap(long address, long fileLength);
+
+ public NativeMMapDirectory(File path) throws IOException {
+ this(path, null);
+ }
+
+ public NativeMMapDirectory(File path, LockFactory lockFactory) throws IOException {
+ super(path, lockFactory);
+ }
+
+ @Override
+ public IndexInput openInput(String name, IOContext context) throws IOException {
+ ensureOpen();
+ File file = new File(getDirectory(), name);
+ //try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
+ return new NativeMMapIndexInput("NativeMMapIndexInput(path=\"" + file.toString() + "\")", new RandomAccessFile(file, "r"));
+ }
+
+ @Override
+ public IndexInputSlicer createSlicer(String name, IOContext context) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ int getFileDes(FileDescriptor fd) {
+ try {
+ Class<?> x = Class.forName("java.io.FileDescriptor");
+ Field f = x.getDeclaredField("fd");
+ f.setAccessible(true);
+ return f.getInt(fd);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static final Unsafe unsafe;
+
+ static {
+ try {
+ Field f = Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe) f.get(null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ static final long arrayBaseOffset = (long) unsafe.arrayBaseOffset(byte[].class);
+
+ private final class NativeMMapIndexInput extends IndexInput {
+
+ private final long address;
+ private final long length;
+ private final RandomAccessFile raf;
+
+ private long pos;
+
+ NativeMMapIndexInput(String resourceDescription, RandomAccessFile raf) throws IOException {
+ super(resourceDescription);
+ this.raf = raf;
+ length = raf.length();
+ int fd = getFileDes(raf.getFD());
+ address = map(fd, length);
+ //System.out.println("map: " + resourceDescription + " fd=" + fd + " -> address=" + address + " length=" + length);
+ pos = address;
+ }
+
+ NativeMMapIndexInput(String resourceDescription, long address, long length, long pos) {
+ super(resourceDescription);
+ raf = null;
+ this.address = address;
+ this.length = length;
+ this.pos = pos;
+ }
+
+ @Override
+ public long getFilePointer() {
+ return pos - address;
+ }
+
+ @Override
+ public void seek(long pos) {
+ this.pos = address + pos;
+ }
+
+ @Override
+ public long length() {
+ return length;
+ }
+
+ @Override
+ public void close() throws IOException {
+ // nocommit guard against double close
+ if (raf != null) {
+ unmap(address, length);
+ raf.close();
+ }
+ }
+
+ @Override
+ public byte readByte() {
+ return unsafe.getByte(pos++);
+ }
+
+ @Override
+ public void readBytes(byte[] b, int offset, int len) {
+ unsafe.copyMemory(null, pos, b, arrayBaseOffset + offset, len);
+ pos += len;
+ }
+
+ @Override
+ public NativeMMapIndexInput clone() {
+ return new NativeMMapIndexInput(toString(), address, length, pos);
+ }
+ }
+}
Property changes on: lucene/misc/src/java/org/apache/lucene/store/NativeMMapDirectory.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/misc/src/java/org/apache/lucene/store/NativeMMapDirectory.cpp
===================================================================
--- lucene/misc/src/java/org/apache/lucene/store/NativeMMapDirectory.cpp (revision 0)
+++ lucene/misc/src/java/org/apache/lucene/store/NativeMMapDirectory.cpp (working copy)
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+//
+// To see assembly:
+//
+// g++ -fpermissive -S -O4 -o test.s -I/usr/local/src/jdk1.6.0_32/include -I/usr/local/src/jdk1.6.0_32/include/linux /l/nativebq/lucene/misc/src/java/org/apache/lucene/search/NativeSearch.cpp
+//
+
+#include <sys/mman.h>
+#include <errno.h>
+#include <jni.h>
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_org_apache_lucene_store_NativeMMapDirectory_map(JNIEnv *env,
+ jclass cl,
+ jint fd, jlong fileLength) {
+ long address = (long) mmap(0, fileLength, PROT_READ, MAP_SHARED, fd, 0);
+ if (address == -1) {
+ // nocommit throw exc
+ printf("errno=%d\n", errno);fflush(stdout);
+ }
+ return address;
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_org_apache_lucene_store_NativeMMapDirectory_unmap(JNIEnv *env,
+ jclass cl,
+ jlong address, jlong fileLength) {
+ munmap((void *) address, fileLength);
+}
Property changes on: lucene/misc/src/java/org/apache/lucene/store/NativeMMapDirectory.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/misc/build.xml
===================================================================
--- lucene/misc/build.xml (revision 1491300)
+++ lucene/misc/build.xml (working copy)
@@ -49,4 +49,51 @@
</cc>
</target>
+ <target name="build-native-search" depends="install-cpptasks">
+ <mkdir dir="${common.build.dir}/native"/>
+
+ <cc outtype="shared" subsystem="console" outfile="${common.build.dir}/native/NativeSearch" >
+ <fileset file="${src.dir}/org/apache/lucene/search/NativeSearch.cpp" />
+ <includepath>
+ <pathelement location="${java.home}/../include"/>
+ <pathelement location="${java.home}/include"/>
+ <pathelement location="${java.home}/../include/linux"/>
+ <pathelement location="${java.home}/../include/solaris"/>
+ </includepath>
+
+ <!--<compilerarg value="-fPIC" />-->
+ <!--<linkerarg value="-lstdc++" />-->
+ <compilerarg value="-fPIC" />
+ <compilerarg value="-O4" />
+ <!--<compilerarg value="-pg" />-->
+ <!--<linkerarg value="-pg" />-->
+ <!--<compilerarg value="-ftree-vectorizer-verbose=3" />-->
+ <!--<compilerarg value="-mtune=native"/>-->
+ <!--<compilerarg value="-march=corei7"/>-->
+ <syslibset libs="stdc++"/>
+ </cc>
+ </target>
+
+ <target name="build-native-mmapdir" depends="install-cpptasks">
+ <mkdir dir="${common.build.dir}/native"/>
+
+ <cc outtype="shared" subsystem="console" outfile="${common.build.dir}/native/NativeMMapDirectory" >
+ <fileset file="${src.dir}/org/apache/lucene/store/NativeMMapDirectory.cpp" />
+ <includepath>
+ <pathelement location="${java.home}/../include"/>
+ <pathelement location="${java.home}/include"/>
+ <pathelement location="${java.home}/../include/linux"/>
+ <pathelement location="${java.home}/../include/solaris"/>
+ </includepath>
+
+ <!--<compilerarg value="-fPIC" />-->
+ <!--<linkerarg value="-lstdc++" />-->
+ <compilerarg value="-fPIC" />
+ <compilerarg value="-O4" />
+ <!--<compilerarg value="-mtune=native"/>-->
+ <!--<compilerarg value="-march=corei7"/>-->
+ <syslibset libs="stdc++"/>
+ </cc>
+ </target>
+
</project>