github.com/tunabay/go-bitarray@v1.3.1/bitarray_compare.go (about)

     1  // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved.
     2  // Use of this source code is governed by the MIT license that can be found in
     3  // the LICENSE file.
     4  
     5  package bitarray
     6  
     7  import (
     8  	"bytes"
     9  )
    10  
    11  // Compare returns an integer comparing two bit arrays lexicographically. The
    12  // result will be 0 if x == y, -1 if x < y, and +1 if y < x. A nil argument is
    13  // equivalent to an empty bit array.
    14  func Compare(x, y BitArrayer) int {
    15  	var bax, bay *BitArray
    16  	if x != nil {
    17  		bax = x.BitArray()
    18  	}
    19  	if y != nil {
    20  		bay = y.BitArray()
    21  	}
    22  	xLen, yLen, xlty := bax.Len(), bay.Len(), -1
    23  	if yLen < xLen {
    24  		bax, bay, xLen, yLen, xlty = bay, bax, yLen, xLen, +1
    25  	}
    26  
    27  	switch {
    28  	case yLen == 0:
    29  		return 0
    30  	case xLen == 0:
    31  		return xlty
    32  	case bax.b == nil:
    33  		if xLen == yLen && (bay.b == nil || allBytesZero(bay.b)) {
    34  			return 0
    35  		}
    36  		return xlty
    37  	case bay.b == nil:
    38  		if allBytesZero(bax.b) {
    39  			if xLen == yLen {
    40  				return 0
    41  			}
    42  			return xlty
    43  		}
    44  		return -xlty
    45  	}
    46  
    47  	ce := bax.nBits >> 3 // end index of common bytes
    48  	cc := bytes.Compare(bax.b[:ce], bay.b[:ce])
    49  	switch {
    50  	case 0 < cc:
    51  		return -xlty
    52  	case cc < 0:
    53  		return xlty
    54  	}
    55  
    56  	if bax.nBits&7 == 0 { // no more x bits
    57  		if xLen == yLen {
    58  			return 0
    59  		}
    60  		return xlty
    61  	}
    62  
    63  	// compare the fractional bits in the last byte
    64  	cs := 8 - bax.nBits&7
    65  	xl, yl := bax.b[ce]>>cs, bay.b[ce]>>cs
    66  	switch {
    67  	case yl < xl:
    68  		return -xlty
    69  	case xl < yl, xLen != yLen:
    70  		return xlty
    71  	}
    72  
    73  	return 0
    74  }
    75  
    76  // Equal returns whether the bit array is the same as specified one.
    77  // nil and zero length bit array are considered to be equal.
    78  func (ba *BitArray) Equal(x BitArrayer) bool {
    79  	var bax *BitArray
    80  	if x != nil {
    81  		bax = x.BitArray()
    82  	}
    83  	switch {
    84  	case ba.IsZero():
    85  		return bax.IsZero()
    86  	case bax.IsZero():
    87  		return false
    88  	case ba.nBits != bax.nBits:
    89  		return false
    90  	case ba.b == nil:
    91  		return bax.b == nil || allBytesZero(bax.b)
    92  	case bax.b == nil:
    93  		return allBytesZero(ba.b)
    94  	}
    95  
    96  	return bytes.Equal(ba.b, bax.b)
    97  }