/// <summary> /// Replaces the bits of the receiver in the given range with the bits of another bit vector. /// Replaces the range <i>[from,to]</i> with the contents of the range <i>[sourceFrom,sourceFrom+to-from]</i>, all inclusive. /// If <i>source==this</i> and the source and destination range intersect in an ambiguous way, then replaces as if using an intermediate auxiliary copy of the receiver. /// <p> /// Optimized for speedd Preliminary performance (200Mhz Pentium Pro, JDK 1.2, NT): replace 10^6 ill aligned bits --> 0.02 seconds elapsed time. /// </summary> /// <param name="from">the start index within the receiver, inclusive.</param> /// <param name="to">the end index within the receiver, inclusive.</param> /// <param name="source">the source bitvector to copy from.</param> /// <param name="sourceFrom">the start index within <i>source</i>, inclusive.</param> /// <exception cref="IndexOutOfRangeException">if <i>Size>0 && (from<0 || from>to || to>=Size || sourceFrom<0 || sourceFrom+to-from+1>source.Count))</i>.</exception> public void ReplaceFromToWith(int from, int to, BitVector source, int sourceFrom) { if (nbits == 0 || to == from - 1) { return; } CheckRangeFromTo(from, to, nbits); int Length = to - from + 1; if (sourceFrom < 0 || sourceFrom + Length > source.Size) { throw new IndexOutOfRangeException(); } if (source.bits == this.bits && from <= sourceFrom && sourceFrom <= to) { // dangerous intersection source = source.Copy(); } long[] theBits = this.bits; // cached for speed. long[] sourceBits = source.bits; // cached for speed. /* * This version is equivalent to the version below but 20 times slower.. * for (int i=from; --Length >= 0; i++, sourceFrom++) { * QuickBitVector.Put(theBits,i,QuickBitVector.Get(sourceBits,sourceFrom)); * } */ // Low level implementation for speed. // This could be done even faster by implementing on even lower levelsd But then the code would probably become a "don't touch" piece. int width = to - from + 1; int blocks = QuickBitVector.Unit(width); // width/64 int bitsPerUnit = QuickBitVector.BITS_PER_UNIT; int bitsPerUnitMinusOne = bitsPerUnit - 1; // copy entire 64 bit blocks, if any. for (int i = blocks; --i >= 0;) { long val1 = QuickBitVector.GetLongFromTo(sourceBits, sourceFrom, sourceFrom + bitsPerUnitMinusOne); QuickBitVector.PutLongFromTo(theBits, val1, from, from + bitsPerUnitMinusOne); sourceFrom += bitsPerUnit; from += bitsPerUnit; } // copy trailing bits, if any. int offset = QuickBitVector.Offset(width); //width%64 long val2 = QuickBitVector.GetLongFromTo(sourceBits, sourceFrom, sourceFrom + offset - 1); QuickBitVector.PutLongFromTo(theBits, val2, from, from + offset - 1); }
/// <summary> /// Returns a long value representing bits of the receiver from index <i>from</i> to index <i>to</i>. /// Bits are returned as a long value with the return value having bit 0 set to bit <code>from</code>, .d, bit <code>to-from</code> set to bit <code>to</code>. /// All other bits of the return value are set to 0. /// If <i>to-from+1==0</i> then returns zero (<i>0L</i>). /// </summary> /// <param name="from">index of start bit (inclusive).</param> /// <param name="to">index of end bit (inclusive).</param> /// <returns>the specified bits as long value.</returns> /// <exception cref="IndexOutOfRangeException">if <i>from<0 || from>=Size || to<0 || to>=Size || to-from+1<0 || to-from+1>64</i></exception> public long GetLongFromTo(int from, int to) { int width = to - from + 1; if (width == 0) { return(0L); } if (from < 0 || from >= nbits || to < 0 || to >= nbits || width < 0 || width > QuickBitVector.BITS_PER_UNIT) { throw new IndexOutOfRangeException("from:" + from + ", to:" + to); } return(QuickBitVector.GetLongFromTo(bits, from, to)); }