@@ -1302,6 +1302,10 @@ main:
13021302
13031303// Xor computes the symmetric difference between two bitmaps and stores the result in the current bitmap
13041304func (rb * Bitmap ) Xor (x2 * Bitmap ) {
1305+ if rb == x2 {
1306+ rb .Clear ()
1307+ return
1308+ }
13051309 pos1 := 0
13061310 pos2 := 0
13071311 length1 := rb .highlowcontainer .size ()
@@ -1316,8 +1320,7 @@ func (rb *Bitmap) Xor(x2 *Bitmap) {
13161320 break
13171321 }
13181322 } else if s1 > s2 {
1319- c := x2 .highlowcontainer .getWritableContainerAtIndex (pos2 )
1320- rb .highlowcontainer .insertNewKeyValueAt (pos1 , x2 .highlowcontainer .getKeyAtIndex (pos2 ), c )
1323+ rb .highlowcontainer .insertNewKeyValueAt (pos1 , x2 .highlowcontainer .getKeyAtIndex (pos2 ), x2 .highlowcontainer .getContainerAtIndex (pos2 ).clone ())
13211324 length1 ++
13221325 pos1 ++
13231326 pos2 ++
@@ -1370,7 +1373,8 @@ main:
13701373 }
13711374 s2 = x2 .highlowcontainer .getKeyAtIndex (pos2 )
13721375 } else {
1373- rb .highlowcontainer .replaceKeyAndContainerAtIndex (pos1 , s1 , rb .highlowcontainer .getUnionedWritableContainer (pos1 , x2 .highlowcontainer .getContainerAtIndex (pos2 )), false )
1376+ newcont := rb .highlowcontainer .getUnionedWritableContainer (pos1 , x2 .highlowcontainer .getContainerAtIndex (pos2 ))
1377+ rb .highlowcontainer .replaceKeyAndContainerAtIndex (pos1 , s1 , newcont , false )
13741378 pos1 ++
13751379 pos2 ++
13761380 if (pos1 == length1 ) || (pos2 == length2 ) {
@@ -1388,6 +1392,10 @@ main:
13881392
13891393// AndNot computes the difference between two bitmaps and stores the result in the current bitmap
13901394func (rb * Bitmap ) AndNot (x2 * Bitmap ) {
1395+ if rb == x2 {
1396+ rb .Clear ()
1397+ return
1398+ }
13911399 pos1 := 0
13921400 pos2 := 0
13931401 intersectionsize := 0
@@ -1543,6 +1551,9 @@ main:
15431551
15441552// Xor computes the symmetric difference between two bitmaps and returns the result
15451553func Xor (x1 , x2 * Bitmap ) * Bitmap {
1554+ if x1 == x2 {
1555+ return NewBitmap ()
1556+ }
15461557 answer := NewBitmap ()
15471558 pos1 := 0
15481559 pos2 := 0
@@ -1580,6 +1591,9 @@ func Xor(x1, x2 *Bitmap) *Bitmap {
15801591
15811592// AndNot computes the difference between two bitmaps and returns the result
15821593func AndNot (x1 , x2 * Bitmap ) * Bitmap {
1594+ if x1 == x2 {
1595+ return NewBitmap ()
1596+ }
15831597 answer := NewBitmap ()
15841598 pos1 := 0
15851599 pos2 := 0
@@ -2145,6 +2159,34 @@ func (rb *Bitmap) Stats() Statistics {
21452159 return stats
21462160}
21472161
2162+ // Describe prints a description of the bitmap's containers to stdout
2163+ func (rb * Bitmap ) Describe () {
2164+ fmt .Printf ("Bitmap with %d containers:\n " , len (rb .highlowcontainer .containers ))
2165+ for i , c := range rb .highlowcontainer .containers {
2166+ key := rb .highlowcontainer .keys [i ]
2167+ shared := ""
2168+ if rb .highlowcontainer .needCopyOnWrite [i ] {
2169+ shared = " (shared)"
2170+ }
2171+ switch c .(type ) {
2172+ case * arrayContainer :
2173+ fmt .Printf (" Container %d (key %d): array, cardinality %d%s\n " , i , key , c .getCardinality (), shared )
2174+ case * bitmapContainer :
2175+ fmt .Printf (" Container %d (key %d): bitmap, cardinality %d%s\n " , i , key , c .getCardinality (), shared )
2176+ case * runContainer16 :
2177+ fmt .Printf (" Container %d (key %d): run, cardinality %d%s\n " , i , key , c .getCardinality (), shared )
2178+ default :
2179+ fmt .Printf (" Container %d (key %d): unknown type, cardinality %d%s\n " , i , key , c .getCardinality (), shared )
2180+ }
2181+ }
2182+ valid := rb .Validate ()
2183+ if valid != nil {
2184+ fmt .Printf (" Bitmap is INVALID: %v\n " , valid )
2185+ } else {
2186+ fmt .Printf (" Bitmap is valid\n " )
2187+ }
2188+ }
2189+
21482190// Validate checks if the bitmap is internally consistent.
21492191// You may call it after deserialization to check that the bitmap is valid.
21502192// This function returns an error if the bitmap is invalid, nil otherwise.
0 commit comments