Advertisement
L_B

OpenBitSet

L_B
Feb 13th, 2012
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 73.61 KB | None | 0 0
  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  * http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17.  
  18. using System;
  19.  
  20.  
  21.  
  22. namespace Lucene.Net.Util
  23. {
  24.  
  25.     /// <summary>An "open" BitSet implementation that allows direct access to the array of words
  26.     /// storing the bits.
  27.     /// <p/>
  28.     /// Unlike java.util.bitset, the fact that bits are packed into an array of longs
  29.     /// is part of the interface.  This allows efficient implementation of other algorithms
  30.     /// by someone other than the author.  It also allows one to efficiently implement
  31.     /// alternate serialization or interchange formats.
  32.     /// <p/>
  33.     /// <code>OpenBitSet</code> is faster than <code>java.util.BitSet</code> in most operations
  34.     /// and *much* faster at calculating cardinality of sets and results of set operations.
  35.     /// It can also handle sets of larger cardinality (up to 64 * 2**32-1)
  36.     /// <p/>
  37.     /// The goals of <code>OpenBitSet</code> are the fastest implementation possible, and
  38.     /// maximum code reuse.  Extra safety and encapsulation
  39.     /// may always be built on top, but if that's built in, the cost can never be removed (and
  40.     /// hence people re-implement their own version in order to get better performance).
  41.     /// If you want a "safe", totally encapsulated (and slower and limited) BitSet
  42.     /// class, use <code>java.util.BitSet</code>.
  43.     /// <p/>
  44.     /// <h3>Performance Results</h3>
  45.     ///
  46.     /// Test system: Pentium 4, Sun Java 1.5_06 -server -Xbatch -Xmx64M
  47.     /// <br/>BitSet size = 1,000,000
  48.     /// <br/>Results are java.util.BitSet time divided by OpenBitSet time.
  49.     /// <table border="1">
  50.     /// <tr>
  51.     /// <th></th> <th>cardinality</th> <th>intersect_count</th> <th>union</th> <th>nextSetBit</th> <th>get</th> <th>iterator</th>
  52.     /// </tr>
  53.     /// <tr>
  54.     /// <th>50% full</th> <td>3.36</td> <td>3.96</td> <td>1.44</td> <td>1.46</td> <td>1.99</td> <td>1.58</td>
  55.     /// </tr>
  56.     /// <tr>
  57.     /// <th>1% full</th> <td>3.31</td> <td>3.90</td> <td>&#160;</td> <td>1.04</td> <td>&#160;</td> <td>0.99</td>
  58.     /// </tr>
  59.     /// </table>
  60.     /// <br/>
  61.     /// Test system: AMD Opteron, 64 bit linux, Sun Java 1.5_06 -server -Xbatch -Xmx64M
  62.     /// <br/>BitSet size = 1,000,000
  63.     /// <br/>Results are java.util.BitSet time divided by OpenBitSet time.
  64.     /// <table border="1">
  65.     /// <tr>
  66.     /// <th></th> <th>cardinality</th> <th>intersect_count</th> <th>union</th> <th>nextSetBit</th> <th>get</th> <th>iterator</th>
  67.     /// </tr>
  68.     /// <tr>
  69.     /// <th>50% full</th> <td>2.50</td> <td>3.50</td> <td>1.00</td> <td>1.03</td> <td>1.12</td> <td>1.25</td>
  70.     /// </tr>
  71.     /// <tr>
  72.     /// <th>1% full</th> <td>2.51</td> <td>3.49</td> <td>&#160;</td> <td>1.00</td> <td>&#160;</td> <td>1.02</td>
  73.     /// </tr>
  74.     /// </table>
  75.     /// </summary>
  76.     /// <version>  $Id$
  77.     /// </version>
  78.  
  79.     [Serializable]
  80.     public class OpenBitSet : System.ICloneable
  81.     {
  82.         protected internal long[] bits;
  83.         protected internal int wlen; // number of words (elements) used in the array
  84.  
  85.         /// <summary>Constructs an OpenBitSet large enough to hold numBits.
  86.         ///
  87.         /// </summary>
  88.         /// <param name="numBits">
  89.         /// </param>
  90.         public OpenBitSet(long numBits)
  91.         {
  92.             bits = new long[Bits2words(numBits)];
  93.             wlen = bits.Length;
  94.         }
  95.  
  96.         public OpenBitSet()
  97.             : this(64)
  98.         {
  99.         }
  100.  
  101.         /// <summary>Constructs an OpenBitSet from an existing long[].
  102.         /// <br/>
  103.         /// The first 64 bits are in long[0],
  104.         /// with bit index 0 at the least significant bit, and bit index 63 at the most significant.
  105.         /// Given a bit index,
  106.         /// the word containing it is long[index/64], and it is at bit number index%64 within that word.
  107.         /// <p/>
  108.         /// numWords are the number of elements in the array that contain
  109.         /// set bits (non-zero longs).
  110.         /// numWords should be &lt;= bits.length, and
  111.         /// any existing words in the array at position &gt;= numWords should be zero.
  112.         ///
  113.         /// </summary>
  114.         public OpenBitSet(long[] bits, int numWords)
  115.         {
  116.             this.bits = bits;
  117.             this.wlen = numWords;
  118.         }
  119.  
  120.         /// <summary>This DocIdSet implementation is cacheable. </summary>
  121.         public bool IsCacheable()
  122.         {
  123.             return true;
  124.         }
  125.  
  126.         /// <summary>Returns the current capacity in bits (1 greater than the index of the last bit) </summary>
  127.         public virtual long Capacity()
  128.         {
  129.             return bits.Length << 6;
  130.         }
  131.  
  132.         /// <summary> Returns the current capacity of this set.  Included for
  133.         /// compatibility.  This is *not* equal to {@link #cardinality}
  134.         /// </summary>
  135.         public virtual long Size()
  136.         {
  137.             return Capacity();
  138.         }
  139.  
  140.         /// <summary>Returns true if there are no set bits </summary>
  141.         public virtual bool IsEmpty()
  142.         {
  143.             return Cardinality() == 0;
  144.         }
  145.  
  146.         /// <summary>Expert: returns the long[] storing the bits </summary>
  147.         public virtual long[] GetBits()
  148.         {
  149.             return bits;
  150.         }
  151.  
  152.         /// <summary>Expert: sets a new long[] to use as the bit storage </summary>
  153.         public virtual void SetBits(long[] bits)
  154.         {
  155.             this.bits = bits;
  156.         }
  157.  
  158.         /// <summary>Expert: gets the number of longs in the array that are in use </summary>
  159.         public virtual int GetNumWords()
  160.         {
  161.             return wlen;
  162.         }
  163.  
  164.         /// <summary>Expert: sets the number of longs in the array that are in use </summary>
  165.         public virtual void SetNumWords(int nWords)
  166.         {
  167.             this.wlen = nWords;
  168.         }
  169.  
  170.  
  171.  
  172.         /// <summary>Returns true or false for the specified bit index. </summary>
  173.         public virtual bool Get(int index)
  174.         {
  175.             int i = index >> 6; // div 64
  176.             // signed shift will keep a negative index and force an
  177.             // array-index-out-of-bounds-exception, removing the need for an explicit check.
  178.             if (i >= bits.Length)
  179.                 return false;
  180.  
  181.             int bit = index & 0x3f; // mod 64
  182.             long bitmask = 1L << bit;
  183.             return (bits[i] & bitmask) != 0;
  184.         }
  185.  
  186.  
  187.         /// <summary>Returns true or false for the specified bit index.
  188.         /// The index should be less than the OpenBitSet size
  189.         /// </summary>
  190.         public virtual bool FastGet(int index)
  191.         {
  192.             int i = index >> 6; // div 64
  193.             // signed shift will keep a negative index and force an
  194.             // array-index-out-of-bounds-exception, removing the need for an explicit check.
  195.             int bit = index & 0x3f; // mod 64
  196.             long bitmask = 1L << bit;
  197.             return (bits[i] & bitmask) != 0;
  198.         }
  199.  
  200.  
  201.  
  202.         /// <summary>Returns true or false for the specified bit index</summary>
  203.         public virtual bool Get(long index)
  204.         {
  205.             int i = (int)(index >> 6); // div 64
  206.             if (i >= bits.Length)
  207.                 return false;
  208.             int bit = (int)index & 0x3f; // mod 64
  209.             long bitmask = 1L << bit;
  210.             return (bits[i] & bitmask) != 0;
  211.         }
  212.  
  213.         /// <summary>Returns true or false for the specified bit index.
  214.         /// The index should be less than the OpenBitSet size.
  215.         /// </summary>
  216.         public virtual bool FastGet(long index)
  217.         {
  218.             int i = (int)(index >> 6); // div 64
  219.             int bit = (int)index & 0x3f; // mod 64
  220.             long bitmask = 1L << bit;
  221.             return (bits[i] & bitmask) != 0;
  222.         }
  223.  
  224.         /*
  225.         // alternate implementation of get()
  226.         public boolean get1(int index) {
  227.         int i = index >> 6;                // div 64
  228.         int bit = index & 0x3f;            // mod 64
  229.         return ((bits[i]>>>bit) & 0x01) != 0;
  230.         // this does a long shift and a bittest (on x86) vs
  231.         // a long shift, and a long AND, (the test for zero is prob a no-op)
  232.         // testing on a P4 indicates this is slower than (bits[i] & bitmask) != 0;
  233.         }
  234.         */
  235.  
  236.  
  237.         /// <summary>returns 1 if the bit is set, 0 if not.
  238.         /// The index should be less than the OpenBitSet size
  239.         /// </summary>
  240.         public virtual int GetBit(int index)
  241.         {
  242.             int i = index >> 6; // div 64
  243.             int bit = index & 0x3f; // mod 64
  244.             return ((int)((ulong)(bits[i]) >> bit)) & 0x01;
  245.         }
  246.  
  247.  
  248.         /*
  249.         public boolean get2(int index) {
  250.         int word = index >> 6;            // div 64
  251.         int bit = index & 0x0000003f;     // mod 64
  252.         return (bits[word] << bit) < 0;   // hmmm, this would work if bit order were reversed
  253.         // we could right shift and check for parity bit, if it was available to us.
  254.         }
  255.         */
  256.  
  257.         /// <summary>sets a bit, expanding the set size if necessary </summary>
  258.         public virtual void Set(long index)
  259.         {
  260.             int wordNum = ExpandingWordNum(index);
  261.             int bit = (int)index & 0x3f;
  262.             long bitmask = 1L << bit;
  263.             bits[wordNum] |= bitmask;
  264.         }
  265.  
  266.  
  267.         /// <summary>Sets the bit at the specified index.
  268.         /// The index should be less than the OpenBitSet size.
  269.         /// </summary>
  270.         public virtual void FastSet(int index)
  271.         {
  272.             int wordNum = index >> 6; // div 64
  273.             int bit = index & 0x3f; // mod 64
  274.             long bitmask = 1L << bit;
  275.             bits[wordNum] |= bitmask;
  276.         }
  277.  
  278.         /// <summary>Sets the bit at the specified index.
  279.         /// The index should be less than the OpenBitSet size.
  280.         /// </summary>
  281.         public virtual void FastSet(long index)
  282.         {
  283.             int wordNum = (int)(index >> 6);
  284.             int bit = (int)index & 0x3f;
  285.             long bitmask = 1L << bit;
  286.             bits[wordNum] |= bitmask;
  287.         }
  288.  
  289.         /// <summary>Sets a range of bits, expanding the set size if necessary
  290.         ///
  291.         /// </summary>
  292.         /// <param name="startIndex">lower index
  293.         /// </param>
  294.         /// <param name="endIndex">one-past the last bit to set
  295.         /// </param>
  296.         public virtual void Set(long startIndex, long endIndex)
  297.         {
  298.             if (endIndex <= startIndex)
  299.                 return;
  300.  
  301.             int startWord = (int)(startIndex >> 6);
  302.  
  303.             // since endIndex is one past the end, this is index of the last
  304.             // word to be changed.
  305.             int endWord = ExpandingWordNum(endIndex - 1);
  306.  
  307.             long startmask = -1L << (int)startIndex;
  308.             long endmask = (long)(0xffffffffffffffffUL >> (int)-endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
  309.  
  310.             if (startWord == endWord)
  311.             {
  312.                 bits[startWord] |= (startmask & endmask);
  313.                 return;
  314.             }
  315.  
  316.             bits[startWord] |= startmask;
  317.             for (int i = startWord + 1; i < endWord; i++)
  318.                 bits[i] = -1L;
  319.             bits[endWord] |= endmask;
  320.         }
  321.  
  322.  
  323.  
  324.         protected internal virtual int ExpandingWordNum(long index)
  325.         {
  326.             int wordNum = (int)(index >> 6);
  327.             if (wordNum >= wlen)
  328.             {
  329.                 EnsureCapacity(index + 1);
  330.                 wlen = wordNum + 1;
  331.             }
  332.             return wordNum;
  333.         }
  334.  
  335.  
  336.         /// <summary>clears a bit.
  337.         /// The index should be less than the OpenBitSet size.
  338.         /// </summary>
  339.         public virtual void FastClear(int index)
  340.         {
  341.             int wordNum = index >> 6;
  342.             int bit = index & 0x03f;
  343.             long bitmask = 1L << bit;
  344.             bits[wordNum] &= ~bitmask;
  345.             // hmmm, it takes one more instruction to clear than it does to set... any
  346.             // way to work around this?  If there were only 63 bits per word, we could
  347.             // use a right shift of 10111111...111 in binary to position the 0 in the
  348.             // correct place (using sign extension).
  349.             // Could also use Long.rotateRight() or rotateLeft() *if* they were converted
  350.             // by the JVM into a native instruction.
  351.             // bits[word] &= Long.rotateLeft(0xfffffffe,bit);
  352.         }
  353.  
  354.         /// <summary>clears a bit.
  355.         /// The index should be less than the OpenBitSet size.
  356.         /// </summary>
  357.         public virtual void FastClear(long index)
  358.         {
  359.             int wordNum = (int)(index >> 6); // div 64
  360.             int bit = (int)index & 0x3f; // mod 64
  361.             long bitmask = 1L << bit;
  362.             bits[wordNum] &= ~bitmask;
  363.         }
  364.  
  365.         /// <summary>clears a bit, allowing access beyond the current set size without changing the size.</summary>
  366.         public virtual void Clear(long index)
  367.         {
  368.             int wordNum = (int)(index >> 6); // div 64
  369.             if (wordNum >= wlen)
  370.                 return;
  371.             int bit = (int)index & 0x3f; // mod 64
  372.             long bitmask = 1L << bit;
  373.             bits[wordNum] &= ~bitmask;
  374.         }
  375.  
  376.         /// <summary>Clears a range of bits.  Clearing past the end does not change the size of the set.
  377.         ///
  378.         /// </summary>
  379.         /// <param name="startIndex">lower index
  380.         /// </param>
  381.         /// <param name="endIndex">one-past the last bit to clear
  382.         /// </param>
  383.         public virtual void Clear(int startIndex, int endIndex)
  384.         {
  385.             if (endIndex <= startIndex)
  386.                 return;
  387.  
  388.             int startWord = (startIndex >> 6);
  389.             if (startWord >= wlen)
  390.                 return;
  391.  
  392.             // since endIndex is one past the end, this is index of the last
  393.             // word to be changed.
  394.             int endWord = ((endIndex - 1) >> 6);
  395.  
  396.             long startmask = -1L << startIndex;
  397.             long endmask = (long)(0xffffffffffffffffUL >> -endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
  398.  
  399.             // invert masks since we are clearing
  400.             startmask = ~startmask;
  401.             endmask = ~endmask;
  402.  
  403.             if (startWord == endWord)
  404.             {
  405.                 bits[startWord] &= (startmask | endmask);
  406.                 return;
  407.             }
  408.  
  409.             bits[startWord] &= startmask;
  410.  
  411.             int middle = System.Math.Min(wlen, endWord);
  412.             for (int i = startWord + 1; i < middle; i++)
  413.                 bits[i] = 0L;
  414.             if (endWord < wlen)
  415.             {
  416.                 bits[endWord] &= endmask;
  417.             }
  418.         }
  419.  
  420.  
  421.         /// <summary>Clears a range of bits.  Clearing past the end does not change the size of the set.
  422.         ///
  423.         /// </summary>
  424.         /// <param name="startIndex">lower index
  425.         /// </param>
  426.         /// <param name="endIndex">one-past the last bit to clear
  427.         /// </param>
  428.         public virtual void Clear(long startIndex, long endIndex)
  429.         {
  430.             if (endIndex <= startIndex)
  431.                 return;
  432.  
  433.             int startWord = (int)(startIndex >> 6);
  434.             if (startWord >= wlen)
  435.                 return;
  436.  
  437.             // since endIndex is one past the end, this is index of the last
  438.             // word to be changed.
  439.             int endWord = (int)((endIndex - 1) >> 6);
  440.  
  441.             long startmask = -1L << (int)startIndex;
  442.             long endmask = (long)(0xffffffffffffffffUL >> (int)-endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
  443.  
  444.             // invert masks since we are clearing
  445.             startmask = ~startmask;
  446.             endmask = ~endmask;
  447.  
  448.             if (startWord == endWord)
  449.             {
  450.                 bits[startWord] &= (startmask | endmask);
  451.                 return;
  452.             }
  453.  
  454.             bits[startWord] &= startmask;
  455.  
  456.             int middle = System.Math.Min(wlen, endWord);
  457.             for (int i = startWord + 1; i < middle; i++)
  458.                 bits[i] = 0L;
  459.             if (endWord < wlen)
  460.             {
  461.                 bits[endWord] &= endmask;
  462.             }
  463.         }
  464.  
  465.  
  466.  
  467.         /// <summary>Sets a bit and returns the previous value.
  468.         /// The index should be less than the OpenBitSet size.
  469.         /// </summary>
  470.         public virtual bool GetAndSet(int index)
  471.         {
  472.             int wordNum = index >> 6; // div 64
  473.             int bit = index & 0x3f; // mod 64
  474.             long bitmask = 1L << bit;
  475.             bool val = (bits[wordNum] & bitmask) != 0;
  476.             bits[wordNum] |= bitmask;
  477.             return val;
  478.         }
  479.  
  480.         /// <summary>Sets a bit and returns the previous value.
  481.         /// The index should be less than the OpenBitSet size.
  482.         /// </summary>
  483.         public virtual bool GetAndSet(long index)
  484.         {
  485.             int wordNum = (int)(index >> 6); // div 64
  486.             int bit = (int)index & 0x3f; // mod 64
  487.             long bitmask = 1L << bit;
  488.             bool val = (bits[wordNum] & bitmask) != 0;
  489.             bits[wordNum] |= bitmask;
  490.             return val;
  491.         }
  492.  
  493.         /// <summary>flips a bit.
  494.         /// The index should be less than the OpenBitSet size.
  495.         /// </summary>
  496.         public virtual void FastFlip(int index)
  497.         {
  498.             int wordNum = index >> 6; // div 64
  499.             int bit = index & 0x3f; // mod 64
  500.             long bitmask = 1L << bit;
  501.             bits[wordNum] ^= bitmask;
  502.         }
  503.  
  504.         /// <summary>flips a bit.
  505.         /// The index should be less than the OpenBitSet size.
  506.         /// </summary>
  507.         public virtual void FastFlip(long index)
  508.         {
  509.             int wordNum = (int)(index >> 6); // div 64
  510.             int bit = (int)index & 0x3f; // mod 64
  511.             long bitmask = 1L << bit;
  512.             bits[wordNum] ^= bitmask;
  513.         }
  514.  
  515.         /// <summary>flips a bit, expanding the set size if necessary </summary>
  516.         public virtual void Flip(long index)
  517.         {
  518.             int wordNum = ExpandingWordNum(index);
  519.             int bit = (int)index & 0x3f; // mod 64
  520.             long bitmask = 1L << bit;
  521.             bits[wordNum] ^= bitmask;
  522.         }
  523.  
  524.         /// <summary>flips a bit and returns the resulting bit value.
  525.         /// The index should be less than the OpenBitSet size.
  526.         /// </summary>
  527.         public virtual bool FlipAndGet(int index)
  528.         {
  529.             int wordNum = index >> 6; // div 64
  530.             int bit = index & 0x3f; // mod 64
  531.             long bitmask = 1L << bit;
  532.             bits[wordNum] ^= bitmask;
  533.             return (bits[wordNum] & bitmask) != 0;
  534.         }
  535.  
  536.         /// <summary>flips a bit and returns the resulting bit value.
  537.         /// The index should be less than the OpenBitSet size.
  538.         /// </summary>
  539.         public virtual bool FlipAndGet(long index)
  540.         {
  541.             int wordNum = (int)(index >> 6); // div 64
  542.             int bit = (int)index & 0x3f; // mod 64
  543.             long bitmask = 1L << bit;
  544.             bits[wordNum] ^= bitmask;
  545.             return (bits[wordNum] & bitmask) != 0;
  546.         }
  547.  
  548.         /// <summary>Flips a range of bits, expanding the set size if necessary
  549.         ///
  550.         /// </summary>
  551.         /// <param name="startIndex">lower index
  552.         /// </param>
  553.         /// <param name="endIndex">one-past the last bit to flip
  554.         /// </param>
  555.         public virtual void Flip(long startIndex, long endIndex)
  556.         {
  557.             if (endIndex <= startIndex)
  558.                 return;
  559.             int startWord = (int)(startIndex >> 6);
  560.  
  561.             // since endIndex is one past the end, this is index of the last
  562.             // word to be changed.
  563.             int endWord = ExpandingWordNum(endIndex - 1);
  564.  
  565.             /*** Grrr, java shifting wraps around so -1L>>>64 == -1
  566.             * for that reason, make sure not to use endmask if the bits to flip will
  567.             * be zero in the last word (redefine endWord to be the last changed...)
  568.             long startmask = -1L << (startIndex & 0x3f);     // example: 11111...111000
  569.             long endmask = -1L >>> (64-(endIndex & 0x3f));   // example: 00111...111111
  570.             ***/
  571.  
  572.             long startmask = -1L << (int)startIndex;
  573.             long endmask = (long)(0xffffffffffffffffUL >> (int)-endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
  574.  
  575.             if (startWord == endWord)
  576.             {
  577.                 bits[startWord] ^= (startmask & endmask);
  578.                 return;
  579.             }
  580.  
  581.             bits[startWord] ^= startmask;
  582.  
  583.             for (int i = startWord + 1; i < endWord; i++)
  584.             {
  585.                 bits[i] = ~bits[i];
  586.             }
  587.  
  588.             bits[endWord] ^= endmask;
  589.         }
  590.  
  591.  
  592.         /*
  593.         public static int pop(long v0, long v1, long v2, long v3) {
  594.         // derived from pop_array by setting last four elems to 0.
  595.         // exchanges one pop() call for 10 elementary operations
  596.         // saving about 7 instructions... is there a better way?
  597.         long twosA=v0 & v1;
  598.         long ones=v0^v1;
  599.        
  600.         long u2=ones^v2;
  601.         long twosB =(ones&v2)|(u2&v3);
  602.         ones=u2^v3;
  603.        
  604.         long fours=(twosA&twosB);
  605.         long twos=twosA^twosB;
  606.        
  607.         return (pop(fours)<<2)
  608.         + (pop(twos)<<1)
  609.         + pop(ones);
  610.        
  611.         }
  612.         */
  613.  
  614.  
  615.         /// <returns> the number of set bits
  616.         /// </returns>
  617.         public virtual long Cardinality()
  618.         {
  619.             return BitUtil.Pop_array(bits, 0, wlen);
  620.         }
  621.  
  622.         /// <summary>Returns the popcount or cardinality of the intersection of the two sets.
  623.         /// Neither set is modified.
  624.         /// </summary>
  625.         public static long IntersectionCount(OpenBitSet a, OpenBitSet b)
  626.         {
  627.             return BitUtil.Pop_intersect(a.bits, b.bits, 0, System.Math.Min(a.wlen, b.wlen));
  628.         }
  629.  
  630.         /// <summary>Returns the popcount or cardinality of the union of the two sets.
  631.         /// Neither set is modified.
  632.         /// </summary>
  633.         public static long UnionCount(OpenBitSet a, OpenBitSet b)
  634.         {
  635.             long tot = BitUtil.Pop_union(a.bits, b.bits, 0, System.Math.Min(a.wlen, b.wlen));
  636.             if (a.wlen < b.wlen)
  637.             {
  638.                 tot += BitUtil.Pop_array(b.bits, a.wlen, b.wlen - a.wlen);
  639.             }
  640.             else if (a.wlen > b.wlen)
  641.             {
  642.                 tot += BitUtil.Pop_array(a.bits, b.wlen, a.wlen - b.wlen);
  643.             }
  644.             return tot;
  645.         }
  646.  
  647.         /// <summary>Returns the popcount or cardinality of "a and not b"
  648.         /// or "intersection(a, not(b))".
  649.         /// Neither set is modified.
  650.         /// </summary>
  651.         public static long AndNotCount(OpenBitSet a, OpenBitSet b)
  652.         {
  653.             long tot = BitUtil.Pop_andnot(a.bits, b.bits, 0, System.Math.Min(a.wlen, b.wlen));
  654.             if (a.wlen > b.wlen)
  655.             {
  656.                 tot += BitUtil.Pop_array(a.bits, b.wlen, a.wlen - b.wlen);
  657.             }
  658.             return tot;
  659.         }
  660.  
  661.         /// <summary>Returns the popcount or cardinality of the exclusive-or of the two sets.
  662.         /// Neither set is modified.
  663.         /// </summary>
  664.         public static long XorCount(OpenBitSet a, OpenBitSet b)
  665.         {
  666.             long tot = BitUtil.Pop_xor(a.bits, b.bits, 0, System.Math.Min(a.wlen, b.wlen));
  667.             if (a.wlen < b.wlen)
  668.             {
  669.                 tot += BitUtil.Pop_array(b.bits, a.wlen, b.wlen - a.wlen);
  670.             }
  671.             else if (a.wlen > b.wlen)
  672.             {
  673.                 tot += BitUtil.Pop_array(a.bits, b.wlen, a.wlen - b.wlen);
  674.             }
  675.             return tot;
  676.         }
  677.  
  678.  
  679.         /// <summary>Returns the index of the first set bit starting at the index specified.
  680.         /// -1 is returned if there are no more set bits.
  681.         /// </summary>
  682.         public virtual int NextSetBit(int index)
  683.         {
  684.             int i = index >> 6;
  685.             if (i >= wlen)
  686.                 return -1;
  687.             int subIndex = index & 0x3f; // index within the word
  688.             long word = bits[i] >> subIndex; // skip all the bits to the right of index
  689.  
  690.             if (word != 0)
  691.             {
  692.                 return (i << 6) + subIndex + BitUtil.Ntz(word);
  693.             }
  694.  
  695.             while (++i < wlen)
  696.             {
  697.                 word = bits[i];
  698.                 if (word != 0)
  699.                     return (i << 6) + BitUtil.Ntz(word);
  700.             }
  701.  
  702.             return -1;
  703.         }
  704.  
  705.         /// <summary>Returns the index of the first set bit starting at the index specified.
  706.         /// -1 is returned if there are no more set bits.
  707.         /// </summary>
  708.         public virtual long NextSetBit(long index)
  709.         {
  710.             int i = (int)(index >> 6);
  711.             if (i >= wlen)
  712.                 return -1;
  713.             int subIndex = (int)index & 0x3f; // index within the word
  714.             long word = (long)((ulong)bits[i] >> subIndex); // skip all the bits to the right of index
  715.  
  716.             if (word != 0)
  717.             {
  718.                 return (((long)i) << 6) + (subIndex + BitUtil.Ntz(word));
  719.             }
  720.  
  721.             while (++i < wlen)
  722.             {
  723.                 word = bits[i];
  724.                 if (word != 0)
  725.                     return (((long)i) << 6) + BitUtil.Ntz(word);
  726.             }
  727.  
  728.             return -1;
  729.         }
  730.  
  731.  
  732.  
  733.  
  734.         public virtual System.Object Clone()
  735.         {
  736.             try
  737.             {
  738.                 OpenBitSet obs = new OpenBitSet((long[])bits.Clone(), wlen);
  739.                 //obs.bits = new long[obs.bits.Length];
  740.                 //obs.bits.CopyTo(obs.bits, 0); // hopefully an array clone is as fast(er) than arraycopy
  741.                 return obs;
  742.             }
  743.             catch (System.Exception e)
  744.             {
  745.                 throw new System.SystemException(e.Message, e);
  746.             }
  747.         }
  748.  
  749.         /// <summary>this = this AND other </summary>
  750.         public virtual void Intersect(OpenBitSet other)
  751.         {
  752.             int newLen = System.Math.Min(this.wlen, other.wlen);
  753.             long[] thisArr = this.bits;
  754.             long[] otherArr = other.bits;
  755.             // testing against zero can be more efficient
  756.             int pos = newLen;
  757.             while (--pos >= 0)
  758.             {
  759.                 thisArr[pos] &= otherArr[pos];
  760.             }
  761.             if (this.wlen > newLen)
  762.             {
  763.                 // fill zeros from the new shorter length to the old length
  764.                 for (int i = newLen; i < this.wlen; i++)
  765.                     bits[i] = 0L;
  766.             }
  767.             this.wlen = newLen;
  768.         }
  769.  
  770.         /// <summary>this = this OR other </summary>
  771.         public virtual void Union(OpenBitSet other)
  772.         {
  773.             int newLen = System.Math.Max(wlen, other.wlen);
  774.             EnsureCapacityWords(newLen);
  775.  
  776.             long[] thisArr = this.bits;
  777.             long[] otherArr = other.bits;
  778.             int pos = System.Math.Min(wlen, other.wlen);
  779.             while (--pos >= 0)
  780.             {
  781.                 thisArr[pos] |= otherArr[pos];
  782.             }
  783.             if (this.wlen < newLen)
  784.             {
  785.                 Array.Copy(otherArr, this.wlen, thisArr, this.wlen, newLen - this.wlen);
  786.             }
  787.             this.wlen = newLen;
  788.         }
  789.  
  790.  
  791.         /// <summary>Remove all elements set in other. this = this AND_NOT other </summary>
  792.         public virtual void Remove(OpenBitSet other)
  793.         {
  794.             int idx = System.Math.Min(wlen, other.wlen);
  795.             long[] thisArr = this.bits;
  796.             long[] otherArr = other.bits;
  797.             while (--idx >= 0)
  798.             {
  799.                 thisArr[idx] &= ~otherArr[idx];
  800.             }
  801.         }
  802.  
  803.         /// <summary>this = this XOR other </summary>
  804.         public virtual void Xor(OpenBitSet other)
  805.         {
  806.             int newLen = System.Math.Max(wlen, other.wlen);
  807.             EnsureCapacityWords(newLen);
  808.  
  809.             long[] thisArr = this.bits;
  810.             long[] otherArr = other.bits;
  811.             int pos = System.Math.Min(wlen, other.wlen);
  812.             while (--pos >= 0)
  813.             {
  814.                 thisArr[pos] ^= otherArr[pos];
  815.             }
  816.             if (this.wlen < newLen)
  817.             {
  818.                 Array.Copy(otherArr, this.wlen, thisArr, this.wlen, newLen - this.wlen);
  819.             }
  820.             this.wlen = newLen;
  821.         }
  822.  
  823.  
  824.         // some BitSet compatability methods
  825.  
  826.         //** see {@link intersect} */
  827.         public virtual void And(OpenBitSet other)
  828.         {
  829.             Intersect(other);
  830.         }
  831.  
  832.         //** see {@link union} */
  833.         public virtual void Or(OpenBitSet other)
  834.         {
  835.             Union(other);
  836.         }
  837.  
  838.         //** see {@link andNot} */
  839.         public virtual void AndNot(OpenBitSet other)
  840.         {
  841.             Remove(other);
  842.         }
  843.  
  844.         /// <summary>returns true if the sets have any elements in common </summary>
  845.         public virtual bool Intersects(OpenBitSet other)
  846.         {
  847.             int pos = System.Math.Min(this.wlen, other.wlen);
  848.             long[] thisArr = this.bits;
  849.             long[] otherArr = other.bits;
  850.             while (--pos >= 0)
  851.             {
  852.                 if ((thisArr[pos] & otherArr[pos]) != 0)
  853.                     return true;
  854.             }
  855.             return false;
  856.         }
  857.  
  858.  
  859.  
  860.         /// <summary>Expand the long[] with the size given as a number of words (64 bit longs).
  861.         /// getNumWords() is unchanged by this call.
  862.         /// </summary>
  863.         public virtual void EnsureCapacityWords(int numWords)
  864.         {
  865.             if (bits.Length < numWords)
  866.             {
  867.                 bits = ArrayUtil.Grow(bits, numWords);
  868.             }
  869.         }
  870.  
  871.         /// <summary>Ensure that the long[] is big enough to hold numBits, expanding it if necessary.
  872.         /// getNumWords() is unchanged by this call.
  873.         /// </summary>
  874.         public virtual void EnsureCapacity(long numBits)
  875.         {
  876.             EnsureCapacityWords(Bits2words(numBits));
  877.         }
  878.  
  879.         /// <summary>Lowers numWords, the number of words in use,
  880.         /// by checking for trailing zero words.
  881.         /// </summary>
  882.         public virtual void TrimTrailingZeros()
  883.         {
  884.             int idx = wlen - 1;
  885.             while (idx >= 0 && bits[idx] == 0)
  886.                 idx--;
  887.             wlen = idx + 1;
  888.         }
  889.  
  890.         /// <summary>returns the number of 64 bit words it would take to hold numBits </summary>
  891.         public static int Bits2words(long numBits)
  892.         {
  893.             return (int)((((numBits - 1) >> 6)) + 1);
  894.         }
  895.  
  896.  
  897.         /// <summary>returns true if both sets have the same bits set </summary>
  898.         public override bool Equals(System.Object o)
  899.         {
  900.             if (this == o)
  901.                 return true;
  902.             if (!(o is OpenBitSet))
  903.                 return false;
  904.             OpenBitSet a;
  905.             OpenBitSet b = (OpenBitSet)o;
  906.             // make a the larger set.
  907.             if (b.wlen > this.wlen)
  908.             {
  909.                 a = b; b = this;
  910.             }
  911.             else
  912.             {
  913.                 a = this;
  914.             }
  915.  
  916.             // check for any set bits out of the range of b
  917.             for (int i = a.wlen - 1; i >= b.wlen; i--)
  918.             {
  919.                 if (a.bits[i] != 0)
  920.                     return false;
  921.             }
  922.  
  923.             for (int i = b.wlen - 1; i >= 0; i--)
  924.             {
  925.                 if (a.bits[i] != b.bits[i])
  926.                     return false;
  927.             }
  928.  
  929.             return true;
  930.         }
  931.  
  932.         public override int GetHashCode()
  933.         {
  934.             // Start with a zero hash and use a mix that results in zero if the input is zero.
  935.             // This effectively truncates trailing zeros without an explicit check.
  936.             long h = 0;
  937.             for (int i = bits.Length; --i >= 0; )
  938.             {
  939.                 h ^= bits[i];
  940.                 h = (h << 1) | (Support.URShift(h, 63)); // rotate left
  941.             }
  942.             // fold leftmost bits into right and add a constant to prevent
  943.             // empty sets from returning 0, which is too common.
  944.             return (int)(((h >> 32) ^ h) + 0x98761234);
  945.         }
  946.  
  947.  
  948.     }
  949.  
  950.     // from org.apache.solr.util rev 555343
  951.  
  952.     /// <summary>A variety of high efficiencly bit twiddling routines.
  953.     ///
  954.     /// </summary>
  955.     /// <version>  $Id$
  956.     /// </version>
  957.     public class BitUtil
  958.     {
  959.  
  960.         /// <summary>Returns the number of bits set in the long </summary>
  961.         public static int Pop(long x)
  962.         {
  963.             /* Hacker's Delight 32 bit pop function:
  964.             * http://www.hackersdelight.org/HDcode/newCode/pop_arrayHS.cc
  965.             *
  966.             int pop(unsigned x) {
  967.             x = x - ((x >> 1) & 0x55555555);
  968.             x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
  969.             x = (x + (x >> 4)) & 0x0F0F0F0F;
  970.             x = x + (x >> 8);
  971.             x = x + (x >> 16);
  972.             return x & 0x0000003F;
  973.             }
  974.             ***/
  975.  
  976.             // 64 bit java version of the C function from above
  977.             x = x - ((Support.URShift(x, 1)) & 0x5555555555555555L);
  978.             x = (x & 0x3333333333333333L) + ((Support.URShift(x, 2)) & 0x3333333333333333L);
  979.             x = (x + (Support.URShift(x, 4))) & 0x0F0F0F0F0F0F0F0FL;
  980.             x = x + (Support.URShift(x, 8));
  981.             x = x + (Support.URShift(x, 16));
  982.             x = x + (Support.URShift(x, 32));
  983.             return ((int)x) & 0x7F;
  984.         }
  985.  
  986.         /// <summary> Returns the number of set bits in an array of longs. </summary>
  987.         public static long Pop_array(long[] A, int wordOffset, int numWords)
  988.         {
  989.             /*
  990.             * Robert Harley and David Seal's bit counting algorithm, as documented
  991.             * in the revisions of Hacker's Delight
  992.             * http://www.hackersdelight.org/revisions.pdf
  993.             * http://www.hackersdelight.org/HDcode/newCode/pop_arrayHS.cc
  994.             *
  995.             * This function was adapted to Java, and extended to use 64 bit words.
  996.             * if only we had access to wider registers like SSE from java...
  997.             *
  998.             * This function can be transformed to compute the popcount of other functions
  999.             * on bitsets via something like this:
  1000.             * sed 's/A\[\([^]]*\)\]/\(A[\1] \& B[\1]\)/g'
  1001.             *
  1002.             */
  1003.             int n = wordOffset + numWords;
  1004.             long tot = 0, tot8 = 0;
  1005.             long ones = 0, twos = 0, fours = 0;
  1006.  
  1007.             int i;
  1008.             for (i = wordOffset; i <= n - 8; i += 8)
  1009.             {
  1010.                 /***  C macro from Hacker's Delight
  1011.                 #define CSA(h,l, a,b,c) \
  1012.                 {unsigned u = a ^ b; unsigned v = c; \
  1013.                 h = (a & b) | (u & v); l = u ^ v;}
  1014.                 ***/
  1015.  
  1016.                 long twosA, twosB, foursA, foursB, eights;
  1017.  
  1018.                 // CSA(twosA, ones, ones, A[i], A[i+1])
  1019.                 {
  1020.                     long b = A[i], c = A[i + 1];
  1021.                     long u = ones ^ b;
  1022.                     twosA = (ones & b) | (u & c);
  1023.                     ones = u ^ c;
  1024.                 }
  1025.                 // CSA(twosB, ones, ones, A[i+2], A[i+3])
  1026.                 {
  1027.                     long b = A[i + 2], c = A[i + 3];
  1028.                     long u = ones ^ b;
  1029.                     twosB = (ones & b) | (u & c);
  1030.                     ones = u ^ c;
  1031.                 }
  1032.                 //CSA(foursA, twos, twos, twosA, twosB)
  1033.                 {
  1034.                     long u = twos ^ twosA;
  1035.                     foursA = (twos & twosA) | (u & twosB);
  1036.                     twos = u ^ twosB;
  1037.                 }
  1038.                 //CSA(twosA, ones, ones, A[i+4], A[i+5])
  1039.                 {
  1040.                     long b = A[i + 4], c = A[i + 5];
  1041.                     long u = ones ^ b;
  1042.                     twosA = (ones & b) | (u & c);
  1043.                     ones = u ^ c;
  1044.                 }
  1045.                 // CSA(twosB, ones, ones, A[i+6], A[i+7])
  1046.                 {
  1047.                     long b = A[i + 6], c = A[i + 7];
  1048.                     long u = ones ^ b;
  1049.                     twosB = (ones & b) | (u & c);
  1050.                     ones = u ^ c;
  1051.                 }
  1052.                 //CSA(foursB, twos, twos, twosA, twosB)
  1053.                 {
  1054.                     long u = twos ^ twosA;
  1055.                     foursB = (twos & twosA) | (u & twosB);
  1056.                     twos = u ^ twosB;
  1057.                 }
  1058.  
  1059.                 //CSA(eights, fours, fours, foursA, foursB)
  1060.                 {
  1061.                     long u = fours ^ foursA;
  1062.                     eights = (fours & foursA) | (u & foursB);
  1063.                     fours = u ^ foursB;
  1064.                 }
  1065.                 tot8 += Pop(eights);
  1066.             }
  1067.  
  1068.             // handle trailing words in a binary-search manner...
  1069.             // derived from the loop above by setting specific elements to 0.
  1070.             // the original method in Hackers Delight used a simple for loop:
  1071.             //   for (i = i; i < n; i++)      // Add in the last elements
  1072.             //  tot = tot + pop(A[i]);
  1073.  
  1074.             if (i <= n - 4)
  1075.             {
  1076.                 long twosA, twosB, foursA, eights;
  1077.                 {
  1078.                     long b = A[i], c = A[i + 1];
  1079.                     long u = ones ^ b;
  1080.                     twosA = (ones & b) | (u & c);
  1081.                     ones = u ^ c;
  1082.                 }
  1083.                 {
  1084.                     long b = A[i + 2], c = A[i + 3];
  1085.                     long u = ones ^ b;
  1086.                     twosB = (ones & b) | (u & c);
  1087.                     ones = u ^ c;
  1088.                 }
  1089.                 {
  1090.                     long u = twos ^ twosA;
  1091.                     foursA = (twos & twosA) | (u & twosB);
  1092.                     twos = u ^ twosB;
  1093.                 }
  1094.                 eights = fours & foursA;
  1095.                 fours = fours ^ foursA;
  1096.  
  1097.                 tot8 += Pop(eights);
  1098.                 i += 4;
  1099.             }
  1100.  
  1101.             if (i <= n - 2)
  1102.             {
  1103.                 long b = A[i], c = A[i + 1];
  1104.                 long u = ones ^ b;
  1105.                 long twosA = (ones & b) | (u & c);
  1106.                 ones = u ^ c;
  1107.  
  1108.                 long foursA = twos & twosA;
  1109.                 twos = twos ^ twosA;
  1110.  
  1111.                 long eights = fours & foursA;
  1112.                 fours = fours ^ foursA;
  1113.  
  1114.                 tot8 += Pop(eights);
  1115.                 i += 2;
  1116.             }
  1117.  
  1118.             if (i < n)
  1119.             {
  1120.                 tot += Pop(A[i]);
  1121.             }
  1122.  
  1123.             tot += (Pop(fours) << 2) + (Pop(twos) << 1) + Pop(ones) + (tot8 << 3);
  1124.  
  1125.             return tot;
  1126.         }
  1127.  
  1128.         /// <summary>Returns the popcount or cardinality of the two sets after an intersection.
  1129.         /// Neither array is modified.
  1130.         /// </summary>
  1131.         public static long Pop_intersect(long[] A, long[] B, int wordOffset, int numWords)
  1132.         {
  1133.             // generated from pop_array via sed 's/A\[\([^]]*\)\]/\(A[\1] \& B[\1]\)/g'
  1134.             int n = wordOffset + numWords;
  1135.             long tot = 0, tot8 = 0;
  1136.             long ones = 0, twos = 0, fours = 0;
  1137.  
  1138.             int i;
  1139.             for (i = wordOffset; i <= n - 8; i += 8)
  1140.             {
  1141.                 long twosA, twosB, foursA, foursB, eights;
  1142.  
  1143.                 // CSA(twosA, ones, ones, (A[i] & B[i]), (A[i+1] & B[i+1]))
  1144.                 {
  1145.                     long b = (A[i] & B[i]), c = (A[i + 1] & B[i + 1]);
  1146.                     long u = ones ^ b;
  1147.                     twosA = (ones & b) | (u & c);
  1148.                     ones = u ^ c;
  1149.                 }
  1150.                 // CSA(twosB, ones, ones, (A[i+2] & B[i+2]), (A[i+3] & B[i+3]))
  1151.                 {
  1152.                     long b = (A[i + 2] & B[i + 2]), c = (A[i + 3] & B[i + 3]);
  1153.                     long u = ones ^ b;
  1154.                     twosB = (ones & b) | (u & c);
  1155.                     ones = u ^ c;
  1156.                 }
  1157.                 //CSA(foursA, twos, twos, twosA, twosB)
  1158.                 {
  1159.                     long u = twos ^ twosA;
  1160.                     foursA = (twos & twosA) | (u & twosB);
  1161.                     twos = u ^ twosB;
  1162.                 }
  1163.                 //CSA(twosA, ones, ones, (A[i+4] & B[i+4]), (A[i+5] & B[i+5]))
  1164.                 {
  1165.                     long b = (A[i + 4] & B[i + 4]), c = (A[i + 5] & B[i + 5]);
  1166.                     long u = ones ^ b;
  1167.                     twosA = (ones & b) | (u & c);
  1168.                     ones = u ^ c;
  1169.                 }
  1170.                 // CSA(twosB, ones, ones, (A[i+6] & B[i+6]), (A[i+7] & B[i+7]))
  1171.                 {
  1172.                     long b = (A[i + 6] & B[i + 6]), c = (A[i + 7] & B[i + 7]);
  1173.                     long u = ones ^ b;
  1174.                     twosB = (ones & b) | (u & c);
  1175.                     ones = u ^ c;
  1176.                 }
  1177.                 //CSA(foursB, twos, twos, twosA, twosB)
  1178.                 {
  1179.                     long u = twos ^ twosA;
  1180.                     foursB = (twos & twosA) | (u & twosB);
  1181.                     twos = u ^ twosB;
  1182.                 }
  1183.  
  1184.                 //CSA(eights, fours, fours, foursA, foursB)
  1185.                 {
  1186.                     long u = fours ^ foursA;
  1187.                     eights = (fours & foursA) | (u & foursB);
  1188.                     fours = u ^ foursB;
  1189.                 }
  1190.                 tot8 += Pop(eights);
  1191.             }
  1192.  
  1193.  
  1194.             if (i <= n - 4)
  1195.             {
  1196.                 long twosA, twosB, foursA, eights;
  1197.                 {
  1198.                     long b = (A[i] & B[i]), c = (A[i + 1] & B[i + 1]);
  1199.                     long u = ones ^ b;
  1200.                     twosA = (ones & b) | (u & c);
  1201.                     ones = u ^ c;
  1202.                 }
  1203.                 {
  1204.                     long b = (A[i + 2] & B[i + 2]), c = (A[i + 3] & B[i + 3]);
  1205.                     long u = ones ^ b;
  1206.                     twosB = (ones & b) | (u & c);
  1207.                     ones = u ^ c;
  1208.                 }
  1209.                 {
  1210.                     long u = twos ^ twosA;
  1211.                     foursA = (twos & twosA) | (u & twosB);
  1212.                     twos = u ^ twosB;
  1213.                 }
  1214.                 eights = fours & foursA;
  1215.                 fours = fours ^ foursA;
  1216.  
  1217.                 tot8 += Pop(eights);
  1218.                 i += 4;
  1219.             }
  1220.  
  1221.             if (i <= n - 2)
  1222.             {
  1223.                 long b = (A[i] & B[i]), c = (A[i + 1] & B[i + 1]);
  1224.                 long u = ones ^ b;
  1225.                 long twosA = (ones & b) | (u & c);
  1226.                 ones = u ^ c;
  1227.  
  1228.                 long foursA = twos & twosA;
  1229.                 twos = twos ^ twosA;
  1230.  
  1231.                 long eights = fours & foursA;
  1232.                 fours = fours ^ foursA;
  1233.  
  1234.                 tot8 += Pop(eights);
  1235.                 i += 2;
  1236.             }
  1237.  
  1238.             if (i < n)
  1239.             {
  1240.                 tot += Pop((A[i] & B[i]));
  1241.             }
  1242.  
  1243.             tot += (Pop(fours) << 2) + (Pop(twos) << 1) + Pop(ones) + (tot8 << 3);
  1244.  
  1245.             return tot;
  1246.         }
  1247.  
  1248.         /// <summary>Returns the popcount or cardinality of the union of two sets.
  1249.         /// Neither array is modified.
  1250.         /// </summary>
  1251.         public static long Pop_union(long[] A, long[] B, int wordOffset, int numWords)
  1252.         {
  1253.             // generated from pop_array via sed 's/A\[\([^]]*\)\]/\(A[\1] \| B[\1]\)/g'
  1254.             int n = wordOffset + numWords;
  1255.             long tot = 0, tot8 = 0;
  1256.             long ones = 0, twos = 0, fours = 0;
  1257.  
  1258.             int i;
  1259.             for (i = wordOffset; i <= n - 8; i += 8)
  1260.             {
  1261.                 /***  C macro from Hacker's Delight
  1262.                 #define CSA(h,l, a,b,c) \
  1263.                 {unsigned u = a ^ b; unsigned v = c; \
  1264.                 h = (a & b) | (u & v); l = u ^ v;}
  1265.                 ***/
  1266.  
  1267.                 long twosA, twosB, foursA, foursB, eights;
  1268.  
  1269.                 // CSA(twosA, ones, ones, (A[i] | B[i]), (A[i+1] | B[i+1]))
  1270.                 {
  1271.                     long b = (A[i] | B[i]), c = (A[i + 1] | B[i + 1]);
  1272.                     long u = ones ^ b;
  1273.                     twosA = (ones & b) | (u & c);
  1274.                     ones = u ^ c;
  1275.                 }
  1276.                 // CSA(twosB, ones, ones, (A[i+2] | B[i+2]), (A[i+3] | B[i+3]))
  1277.                 {
  1278.                     long b = (A[i + 2] | B[i + 2]), c = (A[i + 3] | B[i + 3]);
  1279.                     long u = ones ^ b;
  1280.                     twosB = (ones & b) | (u & c);
  1281.                     ones = u ^ c;
  1282.                 }
  1283.                 //CSA(foursA, twos, twos, twosA, twosB)
  1284.                 {
  1285.                     long u = twos ^ twosA;
  1286.                     foursA = (twos & twosA) | (u & twosB);
  1287.                     twos = u ^ twosB;
  1288.                 }
  1289.                 //CSA(twosA, ones, ones, (A[i+4] | B[i+4]), (A[i+5] | B[i+5]))
  1290.                 {
  1291.                     long b = (A[i + 4] | B[i + 4]), c = (A[i + 5] | B[i + 5]);
  1292.                     long u = ones ^ b;
  1293.                     twosA = (ones & b) | (u & c);
  1294.                     ones = u ^ c;
  1295.                 }
  1296.                 // CSA(twosB, ones, ones, (A[i+6] | B[i+6]), (A[i+7] | B[i+7]))
  1297.                 {
  1298.                     long b = (A[i + 6] | B[i + 6]), c = (A[i + 7] | B[i + 7]);
  1299.                     long u = ones ^ b;
  1300.                     twosB = (ones & b) | (u & c);
  1301.                     ones = u ^ c;
  1302.                 }
  1303.                 //CSA(foursB, twos, twos, twosA, twosB)
  1304.                 {
  1305.                     long u = twos ^ twosA;
  1306.                     foursB = (twos & twosA) | (u & twosB);
  1307.                     twos = u ^ twosB;
  1308.                 }
  1309.  
  1310.                 //CSA(eights, fours, fours, foursA, foursB)
  1311.                 {
  1312.                     long u = fours ^ foursA;
  1313.                     eights = (fours & foursA) | (u & foursB);
  1314.                     fours = u ^ foursB;
  1315.                 }
  1316.                 tot8 += Pop(eights);
  1317.             }
  1318.  
  1319.  
  1320.             if (i <= n - 4)
  1321.             {
  1322.                 long twosA, twosB, foursA, eights;
  1323.                 {
  1324.                     long b = (A[i] | B[i]), c = (A[i + 1] | B[i + 1]);
  1325.                     long u = ones ^ b;
  1326.                     twosA = (ones & b) | (u & c);
  1327.                     ones = u ^ c;
  1328.                 }
  1329.                 {
  1330.                     long b = (A[i + 2] | B[i + 2]), c = (A[i + 3] | B[i + 3]);
  1331.                     long u = ones ^ b;
  1332.                     twosB = (ones & b) | (u & c);
  1333.                     ones = u ^ c;
  1334.                 }
  1335.                 {
  1336.                     long u = twos ^ twosA;
  1337.                     foursA = (twos & twosA) | (u & twosB);
  1338.                     twos = u ^ twosB;
  1339.                 }
  1340.                 eights = fours & foursA;
  1341.                 fours = fours ^ foursA;
  1342.  
  1343.                 tot8 += Pop(eights);
  1344.                 i += 4;
  1345.             }
  1346.  
  1347.             if (i <= n - 2)
  1348.             {
  1349.                 long b = (A[i] | B[i]), c = (A[i + 1] | B[i + 1]);
  1350.                 long u = ones ^ b;
  1351.                 long twosA = (ones & b) | (u & c);
  1352.                 ones = u ^ c;
  1353.  
  1354.                 long foursA = twos & twosA;
  1355.                 twos = twos ^ twosA;
  1356.  
  1357.                 long eights = fours & foursA;
  1358.                 fours = fours ^ foursA;
  1359.  
  1360.                 tot8 += Pop(eights);
  1361.                 i += 2;
  1362.             }
  1363.  
  1364.             if (i < n)
  1365.             {
  1366.                 tot += Pop((A[i] | B[i]));
  1367.             }
  1368.  
  1369.             tot += (Pop(fours) << 2) + (Pop(twos) << 1) + Pop(ones) + (tot8 << 3);
  1370.  
  1371.             return tot;
  1372.         }
  1373.  
  1374.         /// <summary>Returns the popcount or cardinality of A &amp; ~B
  1375.         /// Neither array is modified.
  1376.         /// </summary>
  1377.         public static long Pop_andnot(long[] A, long[] B, int wordOffset, int numWords)
  1378.         {
  1379.             // generated from pop_array via sed 's/A\[\([^]]*\)\]/\(A[\1] \& ~B[\1]\)/g'
  1380.             int n = wordOffset + numWords;
  1381.             long tot = 0, tot8 = 0;
  1382.             long ones = 0, twos = 0, fours = 0;
  1383.  
  1384.             int i;
  1385.             for (i = wordOffset; i <= n - 8; i += 8)
  1386.             {
  1387.                 /***  C macro from Hacker's Delight
  1388.                 #define CSA(h,l, a,b,c) \
  1389.                 {unsigned u = a ^ b; unsigned v = c; \
  1390.                 h = (a & b) | (u & v); l = u ^ v;}
  1391.                 ***/
  1392.  
  1393.                 long twosA, twosB, foursA, foursB, eights;
  1394.  
  1395.                 // CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i+1] & ~B[i+1]))
  1396.                 {
  1397.                     long b = (A[i] & ~B[i]), c = (A[i + 1] & ~B[i + 1]);
  1398.                     long u = ones ^ b;
  1399.                     twosA = (ones & b) | (u & c);
  1400.                     ones = u ^ c;
  1401.                 }
  1402.                 // CSA(twosB, ones, ones, (A[i+2] & ~B[i+2]), (A[i+3] & ~B[i+3]))
  1403.                 {
  1404.                     long b = (A[i + 2] & ~B[i + 2]), c = (A[i + 3] & ~B[i + 3]);
  1405.                     long u = ones ^ b;
  1406.                     twosB = (ones & b) | (u & c);
  1407.                     ones = u ^ c;
  1408.                 }
  1409.                 //CSA(foursA, twos, twos, twosA, twosB)
  1410.                 {
  1411.                     long u = twos ^ twosA;
  1412.                     foursA = (twos & twosA) | (u & twosB);
  1413.                     twos = u ^ twosB;
  1414.                 }
  1415.                 //CSA(twosA, ones, ones, (A[i+4] & ~B[i+4]), (A[i+5] & ~B[i+5]))
  1416.                 {
  1417.                     long b = (A[i + 4] & ~B[i + 4]), c = (A[i + 5] & ~B[i + 5]);
  1418.                     long u = ones ^ b;
  1419.                     twosA = (ones & b) | (u & c);
  1420.                     ones = u ^ c;
  1421.                 }
  1422.                 // CSA(twosB, ones, ones, (A[i+6] & ~B[i+6]), (A[i+7] & ~B[i+7]))
  1423.                 {
  1424.                     long b = (A[i + 6] & ~B[i + 6]), c = (A[i + 7] & ~B[i + 7]);
  1425.                     long u = ones ^ b;
  1426.                     twosB = (ones & b) | (u & c);
  1427.                     ones = u ^ c;
  1428.                 }
  1429.                 //CSA(foursB, twos, twos, twosA, twosB)
  1430.                 {
  1431.                     long u = twos ^ twosA;
  1432.                     foursB = (twos & twosA) | (u & twosB);
  1433.                     twos = u ^ twosB;
  1434.                 }
  1435.  
  1436.                 //CSA(eights, fours, fours, foursA, foursB)
  1437.                 {
  1438.                     long u = fours ^ foursA;
  1439.                     eights = (fours & foursA) | (u & foursB);
  1440.                     fours = u ^ foursB;
  1441.                 }
  1442.                 tot8 += Pop(eights);
  1443.             }
  1444.  
  1445.  
  1446.             if (i <= n - 4)
  1447.             {
  1448.                 long twosA, twosB, foursA, eights;
  1449.                 {
  1450.                     long b = (A[i] & ~B[i]), c = (A[i + 1] & ~B[i + 1]);
  1451.                     long u = ones ^ b;
  1452.                     twosA = (ones & b) | (u & c);
  1453.                     ones = u ^ c;
  1454.                 }
  1455.                 {
  1456.                     long b = (A[i + 2] & ~B[i + 2]), c = (A[i + 3] & ~B[i + 3]);
  1457.                     long u = ones ^ b;
  1458.                     twosB = (ones & b) | (u & c);
  1459.                     ones = u ^ c;
  1460.                 }
  1461.                 {
  1462.                     long u = twos ^ twosA;
  1463.                     foursA = (twos & twosA) | (u & twosB);
  1464.                     twos = u ^ twosB;
  1465.                 }
  1466.                 eights = fours & foursA;
  1467.                 fours = fours ^ foursA;
  1468.  
  1469.                 tot8 += Pop(eights);
  1470.                 i += 4;
  1471.             }
  1472.  
  1473.             if (i <= n - 2)
  1474.             {
  1475.                 long b = (A[i] & ~B[i]), c = (A[i + 1] & ~B[i + 1]);
  1476.                 long u = ones ^ b;
  1477.                 long twosA = (ones & b) | (u & c);
  1478.                 ones = u ^ c;
  1479.  
  1480.                 long foursA = twos & twosA;
  1481.                 twos = twos ^ twosA;
  1482.  
  1483.                 long eights = fours & foursA;
  1484.                 fours = fours ^ foursA;
  1485.  
  1486.                 tot8 += Pop(eights);
  1487.                 i += 2;
  1488.             }
  1489.  
  1490.             if (i < n)
  1491.             {
  1492.                 tot += Pop((A[i] & ~B[i]));
  1493.             }
  1494.  
  1495.             tot += (Pop(fours) << 2) + (Pop(twos) << 1) + Pop(ones) + (tot8 << 3);
  1496.  
  1497.             return tot;
  1498.         }
  1499.  
  1500.         public static long Pop_xor(long[] A, long[] B, int wordOffset, int numWords)
  1501.         {
  1502.             int n = wordOffset + numWords;
  1503.             long tot = 0, tot8 = 0;
  1504.             long ones = 0, twos = 0, fours = 0;
  1505.  
  1506.             int i;
  1507.             for (i = wordOffset; i <= n - 8; i += 8)
  1508.             {
  1509.                 /***  C macro from Hacker's Delight
  1510.                 #define CSA(h,l, a,b,c) \
  1511.                 {unsigned u = a ^ b; unsigned v = c; \
  1512.                 h = (a & b) | (u & v); l = u ^ v;}
  1513.                 ***/
  1514.  
  1515.                 long twosA, twosB, foursA, foursB, eights;
  1516.  
  1517.                 // CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i+1] ^ B[i+1]))
  1518.                 {
  1519.                     long b = (A[i] ^ B[i]), c = (A[i + 1] ^ B[i + 1]);
  1520.                     long u = ones ^ b;
  1521.                     twosA = (ones & b) | (u & c);
  1522.                     ones = u ^ c;
  1523.                 }
  1524.                 // CSA(twosB, ones, ones, (A[i+2] ^ B[i+2]), (A[i+3] ^ B[i+3]))
  1525.                 {
  1526.                     long b = (A[i + 2] ^ B[i + 2]), c = (A[i + 3] ^ B[i + 3]);
  1527.                     long u = ones ^ b;
  1528.                     twosB = (ones & b) | (u & c);
  1529.                     ones = u ^ c;
  1530.                 }
  1531.                 //CSA(foursA, twos, twos, twosA, twosB)
  1532.                 {
  1533.                     long u = twos ^ twosA;
  1534.                     foursA = (twos & twosA) | (u & twosB);
  1535.                     twos = u ^ twosB;
  1536.                 }
  1537.                 //CSA(twosA, ones, ones, (A[i+4] ^ B[i+4]), (A[i+5] ^ B[i+5]))
  1538.                 {
  1539.                     long b = (A[i + 4] ^ B[i + 4]), c = (A[i + 5] ^ B[i + 5]);
  1540.                     long u = ones ^ b;
  1541.                     twosA = (ones & b) | (u & c);
  1542.                     ones = u ^ c;
  1543.                 }
  1544.                 // CSA(twosB, ones, ones, (A[i+6] ^ B[i+6]), (A[i+7] ^ B[i+7]))
  1545.                 {
  1546.                     long b = (A[i + 6] ^ B[i + 6]), c = (A[i + 7] ^ B[i + 7]);
  1547.                     long u = ones ^ b;
  1548.                     twosB = (ones & b) | (u & c);
  1549.                     ones = u ^ c;
  1550.                 }
  1551.                 //CSA(foursB, twos, twos, twosA, twosB)
  1552.                 {
  1553.                     long u = twos ^ twosA;
  1554.                     foursB = (twos & twosA) | (u & twosB);
  1555.                     twos = u ^ twosB;
  1556.                 }
  1557.  
  1558.                 //CSA(eights, fours, fours, foursA, foursB)
  1559.                 {
  1560.                     long u = fours ^ foursA;
  1561.                     eights = (fours & foursA) | (u & foursB);
  1562.                     fours = u ^ foursB;
  1563.                 }
  1564.                 tot8 += Pop(eights);
  1565.             }
  1566.  
  1567.  
  1568.             if (i <= n - 4)
  1569.             {
  1570.                 long twosA, twosB, foursA, eights;
  1571.                 {
  1572.                     long b = (A[i] ^ B[i]), c = (A[i + 1] ^ B[i + 1]);
  1573.                     long u = ones ^ b;
  1574.                     twosA = (ones & b) | (u & c);
  1575.                     ones = u ^ c;
  1576.                 }
  1577.                 {
  1578.                     long b = (A[i + 2] ^ B[i + 2]), c = (A[i + 3] ^ B[i + 3]);
  1579.                     long u = ones ^ b;
  1580.                     twosB = (ones & b) | (u & c);
  1581.                     ones = u ^ c;
  1582.                 }
  1583.                 {
  1584.                     long u = twos ^ twosA;
  1585.                     foursA = (twos & twosA) | (u & twosB);
  1586.                     twos = u ^ twosB;
  1587.                 }
  1588.                 eights = fours & foursA;
  1589.                 fours = fours ^ foursA;
  1590.  
  1591.                 tot8 += Pop(eights);
  1592.                 i += 4;
  1593.             }
  1594.  
  1595.             if (i <= n - 2)
  1596.             {
  1597.                 long b = (A[i] ^ B[i]), c = (A[i + 1] ^ B[i + 1]);
  1598.                 long u = ones ^ b;
  1599.                 long twosA = (ones & b) | (u & c);
  1600.                 ones = u ^ c;
  1601.  
  1602.                 long foursA = twos & twosA;
  1603.                 twos = twos ^ twosA;
  1604.  
  1605.                 long eights = fours & foursA;
  1606.                 fours = fours ^ foursA;
  1607.  
  1608.                 tot8 += Pop(eights);
  1609.                 i += 2;
  1610.             }
  1611.  
  1612.             if (i < n)
  1613.             {
  1614.                 tot += Pop((A[i] ^ B[i]));
  1615.             }
  1616.  
  1617.             tot += (Pop(fours) << 2) + (Pop(twos) << 1) + Pop(ones) + (tot8 << 3);
  1618.  
  1619.             return tot;
  1620.         }
  1621.  
  1622.         /* python code to generate ntzTable
  1623.         def ntz(val):
  1624.         if val==0: return 8
  1625.         i=0
  1626.         while (val&0x01)==0:
  1627.         i = i+1
  1628.         val >>= 1
  1629.         return i
  1630.         print ','.join([ str(ntz(i)) for i in range(256) ])
  1631.         ***/
  1632.         /// <summary>table of number of trailing zeros in a byte </summary>
  1633.         public static readonly sbyte[] ntzTable = new sbyte[] { 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
  1634.  
  1635.  
  1636.         /// <summary>Returns number of trailing zeros in a 64 bit long value. </summary>
  1637.         public static int Ntz(long val)
  1638.         {
  1639.             // A full binary search to determine the low byte was slower than
  1640.             // a linear search for nextSetBit().  This is most likely because
  1641.             // the implementation of nextSetBit() shifts bits to the right, increasing
  1642.             // the probability that the first non-zero byte is in the rhs.
  1643.             //
  1644.             // This implementation does a single binary search at the top level only
  1645.             // so that all other bit shifting can be done on ints instead of longs to
  1646.             // remain friendly to 32 bit architectures.  In addition, the case of a
  1647.             // non-zero first byte is checked for first because it is the most common
  1648.             // in dense bit arrays.
  1649.  
  1650.             int lower = (int)val;
  1651.             int lowByte = lower & 0xff;
  1652.             if (lowByte != 0)
  1653.                 return ntzTable[lowByte];
  1654.  
  1655.             if (lower != 0)
  1656.             {
  1657.                 lowByte = (Support.URShift(lower, 8)) & 0xff;
  1658.                 if (lowByte != 0)
  1659.                     return ntzTable[lowByte] + 8;
  1660.                 lowByte = (Support.URShift(lower, 16)) & 0xff;
  1661.                 if (lowByte != 0)
  1662.                     return ntzTable[lowByte] + 16;
  1663.                 // no need to mask off low byte for the last byte in the 32 bit word
  1664.                 // no need to check for zero on the last byte either.
  1665.                 return ntzTable[Support.URShift(lower, 24)] + 24;
  1666.             }
  1667.             else
  1668.             {
  1669.                 // grab upper 32 bits
  1670.                 int upper = (int)(val >> 32);
  1671.                 lowByte = upper & 0xff;
  1672.                 if (lowByte != 0)
  1673.                     return ntzTable[lowByte] + 32;
  1674.                 lowByte = (Support.URShift(upper, 8)) & 0xff;
  1675.                 if (lowByte != 0)
  1676.                     return ntzTable[lowByte] + 40;
  1677.                 lowByte = (Support.URShift(upper, 16)) & 0xff;
  1678.                 if (lowByte != 0)
  1679.                     return ntzTable[lowByte] + 48;
  1680.                 // no need to mask off low byte for the last byte in the 32 bit word
  1681.                 // no need to check for zero on the last byte either.
  1682.                 return ntzTable[Support.URShift(upper, 24)] + 56;
  1683.             }
  1684.         }
  1685.  
  1686.         /// <summary>Returns number of trailing zeros in a 32 bit int value. </summary>
  1687.         public static int Ntz(int val)
  1688.         {
  1689.             // This implementation does a single binary search at the top level only.
  1690.             // In addition, the case of a non-zero first byte is checked for first
  1691.             // because it is the most common in dense bit arrays.
  1692.  
  1693.             int lowByte = val & 0xff;
  1694.             if (lowByte != 0)
  1695.                 return ntzTable[lowByte];
  1696.             lowByte = (Support.URShift(val, 8)) & 0xff;
  1697.             if (lowByte != 0)
  1698.                 return ntzTable[lowByte] + 8;
  1699.             lowByte = (Support.URShift(val, 16)) & 0xff;
  1700.             if (lowByte != 0)
  1701.                 return ntzTable[lowByte] + 16;
  1702.             // no need to mask off low byte for the last byte.
  1703.             // no need to check for zero on the last byte either.
  1704.             return ntzTable[Support.URShift(val, 24)] + 24;
  1705.         }
  1706.  
  1707.         /// <summary>returns 0 based index of first set bit
  1708.         /// (only works for x!=0)
  1709.         /// <br/> This is an alternate implementation of ntz()
  1710.         /// </summary>
  1711.         public static int Ntz2(long x)
  1712.         {
  1713.             int n = 0;
  1714.             int y = (int)x;
  1715.             if (y == 0)
  1716.             {
  1717.                 n += 32; y = (int)(Support.URShift(x, 32));
  1718.             } // the only 64 bit shift necessary
  1719.             if ((y & 0x0000FFFF) == 0)
  1720.             {
  1721.                 n += 16; y = Support.URShift(y, 16);
  1722.             }
  1723.             if ((y & 0x000000FF) == 0)
  1724.             {
  1725.                 n += 8; y = Support.URShift(y, 8);
  1726.             }
  1727.             return (ntzTable[y & 0xff]) + n;
  1728.         }
  1729.  
  1730.         /// <summary>returns 0 based index of first set bit
  1731.         /// <br/> This is an alternate implementation of ntz()
  1732.         /// </summary>
  1733.         public static int Ntz3(long x)
  1734.         {
  1735.             // another implementation taken from Hackers Delight, extended to 64 bits
  1736.             // and converted to Java.
  1737.             // Many 32 bit ntz algorithms are at http://www.hackersdelight.org/HDcode/ntz.cc
  1738.             int n = 1;
  1739.  
  1740.             // do the first step as a long, all others as ints.
  1741.             int y = (int)x;
  1742.             if (y == 0)
  1743.             {
  1744.                 n += 32; y = (int)(Support.URShift(x, 32));
  1745.             }
  1746.             if ((y & 0x0000FFFF) == 0)
  1747.             {
  1748.                 n += 16; y = Support.URShift(y, 16);
  1749.             }
  1750.             if ((y & 0x000000FF) == 0)
  1751.             {
  1752.                 n += 8; y = Support.URShift(y, 8);
  1753.             }
  1754.             if ((y & 0x0000000F) == 0)
  1755.             {
  1756.                 n += 4; y = Support.URShift(y, 4);
  1757.             }
  1758.             if ((y & 0x00000003) == 0)
  1759.             {
  1760.                 n += 2; y = Support.URShift(y, 2);
  1761.             }
  1762.             return n - (y & 1);
  1763.         }
  1764.  
  1765.  
  1766.         /// <summary>returns true if v is a power of two or zero</summary>
  1767.         public static bool IsPowerOfTwo(int v)
  1768.         {
  1769.             return ((v & (v - 1)) == 0);
  1770.         }
  1771.  
  1772.         /// <summary>returns true if v is a power of two or zero</summary>
  1773.         public static bool IsPowerOfTwo(long v)
  1774.         {
  1775.             return ((v & (v - 1)) == 0);
  1776.         }
  1777.  
  1778.         /// <summary>returns the next highest power of two, or the current value if it's already a power of two or zero</summary>
  1779.         public static int NextHighestPowerOfTwo(int v)
  1780.         {
  1781.             v--;
  1782.             v |= v >> 1;
  1783.             v |= v >> 2;
  1784.             v |= v >> 4;
  1785.             v |= v >> 8;
  1786.             v |= v >> 16;
  1787.             v++;
  1788.             return v;
  1789.         }
  1790.  
  1791.         /// <summary>returns the next highest power of two, or the current value if it's already a power of two or zero</summary>
  1792.         public static long NextHighestPowerOfTwo(long v)
  1793.         {
  1794.             v--;
  1795.             v |= v >> 1;
  1796.             v |= v >> 2;
  1797.             v |= v >> 4;
  1798.             v |= v >> 8;
  1799.             v |= v >> 16;
  1800.             v |= v >> 32;
  1801.             v++;
  1802.             return v;
  1803.         }
  1804.     }
  1805.  
  1806.     /// <summary> Methods for manipulating arrays.</summary>
  1807.     public sealed class ArrayUtil
  1808.     {
  1809.         /*
  1810.         Begin Apache Harmony code
  1811.        
  1812.         Revision taken on Friday, June 12. https://svn.apache.org/repos/asf/harmony/enhanced/classlib/archive/java6/modules/luni/src/main/java/java/lang/Integer.java
  1813.        
  1814.         */
  1815.  
  1816.         /// <summary> Parses the string argument as if it was an int value and returns the
  1817.         /// result. Throws NumberFormatException if the string does not represent an
  1818.         /// int quantity.
  1819.         ///
  1820.         /// </summary>
  1821.         /// <param name="chars">a string representation of an int quantity.
  1822.         /// </param>
  1823.         /// <returns> int the value represented by the argument
  1824.         /// </returns>
  1825.         /// <throws>  NumberFormatException if the argument could not be parsed as an int quantity. </throws>
  1826.         public static int ParseInt(char[] chars)
  1827.         {
  1828.             return ParseInt(chars, 0, chars.Length, 10);
  1829.         }
  1830.  
  1831.         /// <summary> Parses a char array into an int.</summary>
  1832.         /// <param name="chars">the character array
  1833.         /// </param>
  1834.         /// <param name="offset">The offset into the array
  1835.         /// </param>
  1836.         /// <param name="len">The length
  1837.         /// </param>
  1838.         /// <returns> the int
  1839.         /// </returns>
  1840.         /// <throws>  NumberFormatException if it can't parse </throws>
  1841.         public static int ParseInt(char[] chars, int offset, int len)
  1842.         {
  1843.             return ParseInt(chars, offset, len, 10);
  1844.         }
  1845.  
  1846.         /// <summary> Parses the string argument as if it was an int value and returns the
  1847.         /// result. Throws NumberFormatException if the string does not represent an
  1848.         /// int quantity. The second argument specifies the radix to use when parsing
  1849.         /// the value.
  1850.         ///
  1851.         /// </summary>
  1852.         /// <param name="chars">a string representation of an int quantity.
  1853.         /// </param>
  1854.         /// <param name="radix">the base to use for conversion.
  1855.         /// </param>
  1856.         /// <returns> int the value represented by the argument
  1857.         /// </returns>
  1858.         /// <throws>  NumberFormatException if the argument could not be parsed as an int quantity. </throws>
  1859.         public static int ParseInt(char[] chars, int offset, int len, int radix)
  1860.         {
  1861.             if (chars == null || radix < 2 || radix > 36)
  1862.             {
  1863.                 throw new System.FormatException();
  1864.             }
  1865.             int i = 0;
  1866.             if (len == 0)
  1867.             {
  1868.                 throw new System.FormatException("chars length is 0");
  1869.             }
  1870.             bool negative = chars[offset + i] == '-';
  1871.             if (negative && ++i == len)
  1872.             {
  1873.                 throw new System.FormatException("can't convert to an int");
  1874.             }
  1875.             if (negative == true)
  1876.             {
  1877.                 offset++;
  1878.                 len--;
  1879.             }
  1880.             return Parse(chars, offset, len, radix, negative);
  1881.         }
  1882.  
  1883.  
  1884.         private static int Parse(char[] chars, int offset, int len, int radix, bool negative)
  1885.         {
  1886.             int max = System.Int32.MinValue / radix;
  1887.             int result = 0;
  1888.             for (int i = 0; i < len; i++)
  1889.             {
  1890.                 int digit = (int)System.Char.GetNumericValue(chars[i + offset]);
  1891.                 if (digit == -1)
  1892.                 {
  1893.                     throw new System.FormatException("Unable to parse");
  1894.                 }
  1895.                 if (max > result)
  1896.                 {
  1897.                     throw new System.FormatException("Unable to parse");
  1898.                 }
  1899.                 int next = result * radix - digit;
  1900.                 if (next > result)
  1901.                 {
  1902.                     throw new System.FormatException("Unable to parse");
  1903.                 }
  1904.                 result = next;
  1905.             }
  1906.             /*while (offset < len) {
  1907.            
  1908.             }*/
  1909.             if (!negative)
  1910.             {
  1911.                 result = -result;
  1912.                 if (result < 0)
  1913.                 {
  1914.                     throw new System.FormatException("Unable to parse");
  1915.                 }
  1916.             }
  1917.             return result;
  1918.         }
  1919.  
  1920.  
  1921.         /*
  1922.        
  1923.         END APACHE HARMONY CODE
  1924.         */
  1925.  
  1926.  
  1927.         public static int GetNextSize(int targetSize)
  1928.         {
  1929.             /* This over-allocates proportional to the list size, making room
  1930.             * for additional growth.  The over-allocation is mild, but is
  1931.             * enough to give linear-time amortized behavior over a long
  1932.             * sequence of appends() in the presence of a poorly-performing
  1933.             * system realloc().
  1934.             * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
  1935.             */
  1936.             return (targetSize >> 3) + (targetSize < 9 ? 3 : 6) + targetSize;
  1937.         }
  1938.  
  1939.         public static int GetShrinkSize(int currentSize, int targetSize)
  1940.         {
  1941.             int newSize = GetNextSize(targetSize);
  1942.             // Only reallocate if we are "substantially" smaller.
  1943.             // This saves us from "running hot" (constantly making a
  1944.             // bit bigger then a bit smaller, over and over):
  1945.             if (newSize < currentSize / 2)
  1946.                 return newSize;
  1947.             else
  1948.                 return currentSize;
  1949.         }
  1950.  
  1951.         public static int[] Grow(int[] array, int minSize)
  1952.         {
  1953.             if (array.Length < minSize)
  1954.             {
  1955.                 int[] newArray = new int[GetNextSize(minSize)];
  1956.                 Array.Copy(array, 0, newArray, 0, array.Length);
  1957.                 return newArray;
  1958.             }
  1959.             else
  1960.                 return array;
  1961.         }
  1962.  
  1963.         public static int[] Grow(int[] array)
  1964.         {
  1965.             return Grow(array, 1 + array.Length);
  1966.         }
  1967.  
  1968.         public static int[] Shrink(int[] array, int targetSize)
  1969.         {
  1970.             int newSize = GetShrinkSize(array.Length, targetSize);
  1971.             if (newSize != array.Length)
  1972.             {
  1973.                 int[] newArray = new int[newSize];
  1974.                 Array.Copy(array, 0, newArray, 0, newSize);
  1975.                 return newArray;
  1976.             }
  1977.             else
  1978.                 return array;
  1979.         }
  1980.  
  1981.         public static long[] Grow(long[] array, int minSize)
  1982.         {
  1983.             if (array.Length < minSize)
  1984.             {
  1985.                 long[] newArray = new long[GetNextSize(minSize)];
  1986.                 Array.Copy(array, 0, newArray, 0, array.Length);
  1987.                 return newArray;
  1988.             }
  1989.             else
  1990.                 return array;
  1991.         }
  1992.  
  1993.         public static long[] Grow(long[] array)
  1994.         {
  1995.             return Grow(array, 1 + array.Length);
  1996.         }
  1997.  
  1998.         public static long[] Shrink(long[] array, int targetSize)
  1999.         {
  2000.             int newSize = GetShrinkSize(array.Length, targetSize);
  2001.             if (newSize != array.Length)
  2002.             {
  2003.                 long[] newArray = new long[newSize];
  2004.                 Array.Copy(array, 0, newArray, 0, newSize);
  2005.                 return newArray;
  2006.             }
  2007.             else
  2008.                 return array;
  2009.         }
  2010.  
  2011.         public static byte[] Grow(byte[] array, int minSize)
  2012.         {
  2013.             if (array.Length < minSize)
  2014.             {
  2015.                 byte[] newArray = new byte[GetNextSize(minSize)];
  2016.                 Array.Copy(array, 0, newArray, 0, array.Length);
  2017.                 return newArray;
  2018.             }
  2019.             else
  2020.                 return array;
  2021.         }
  2022.  
  2023.         public static byte[] Grow(byte[] array)
  2024.         {
  2025.             return Grow(array, 1 + array.Length);
  2026.         }
  2027.  
  2028.         public static byte[] Shrink(byte[] array, int targetSize)
  2029.         {
  2030.             int newSize = GetShrinkSize(array.Length, targetSize);
  2031.             if (newSize != array.Length)
  2032.             {
  2033.                 byte[] newArray = new byte[newSize];
  2034.                 Array.Copy(array, 0, newArray, 0, newSize);
  2035.                 return newArray;
  2036.             }
  2037.             else
  2038.                 return array;
  2039.         }
  2040.  
  2041.         /// <summary> Returns hash of chars in range start (inclusive) to
  2042.         /// end (inclusive)
  2043.         /// </summary>
  2044.         public static int HashCode(char[] array, int start, int end)
  2045.         {
  2046.             int code = 0;
  2047.             for (int i = end - 1; i >= start; i--)
  2048.                 code = code * 31 + array[i];
  2049.             return code;
  2050.         }
  2051.  
  2052.         /// <summary> Returns hash of chars in range start (inclusive) to
  2053.         /// end (inclusive)
  2054.         /// </summary>
  2055.         public static int HashCode(byte[] array, int start, int end)
  2056.         {
  2057.             int code = 0;
  2058.             for (int i = end - 1; i >= start; i--)
  2059.                 code = code * 31 + array[i];
  2060.             return code;
  2061.         }
  2062.     }
  2063.  
  2064.     public class Support
  2065.     {
  2066.         /// <summary>
  2067.         /// Performs an unsigned bitwise right shift with the specified number
  2068.         /// </summary>
  2069.         /// <param name="number">Number to operate on</param>
  2070.         /// <param name="bits">Ammount of bits to shift</param>
  2071.         /// <returns>The resulting number from the shift operation</returns>
  2072.         public static int URShift(int number, int bits)
  2073.         {
  2074.             return (int)(((uint)number) >> bits);
  2075.         }
  2076.  
  2077.         /// <summary>
  2078.         /// Performs an unsigned bitwise right shift with the specified number
  2079.         /// </summary>
  2080.         /// <param name="number">Number to operate on</param>
  2081.         /// <param name="bits">Ammount of bits to shift</param>
  2082.         /// <returns>The resulting number from the shift operation</returns>
  2083.         public static long URShift(long number, int bits)
  2084.         {
  2085.             return (long)(((ulong)number) >> bits);
  2086.         }
  2087.     }
  2088. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement