summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/RoaringBitmap
diff options
context:
space:
mode:
authortechknowlogick <techknowlogick@gitea.io>2021-07-07 15:41:05 -0400
committerGitHub <noreply@github.com>2021-07-07 15:41:05 -0400
commit7613f31c6b2101d1e3affa74effc6efc5d3752ea (patch)
tree11d40a7372829d1bc89a43d7abda03c4530b8478 /vendor/github.com/RoaringBitmap
parent9543e068e960e65dba62b7f60dd6144a1724d718 (diff)
downloadgitea-7613f31c6b2101d1e3affa74effc6efc5d3752ea.tar.gz
gitea-7613f31c6b2101d1e3affa74effc6efc5d3752ea.zip
Update vendor 20210707 (#16366)
* update gitea.com/go-chi/binding * update github.com/blevesearch/bleve/v2 * update github.com/caddyserver/certmagic * update github.com/go-git/go-git/v5 * update github.com/lafriks/xormstore * update github.com/yuin/goldmark * Revert "update gitea.com/go-chi/binding" This reverts commit dea2f292b116114f9316fab95c5fd124174da404.
Diffstat (limited to 'vendor/github.com/RoaringBitmap')
-rw-r--r--vendor/github.com/RoaringBitmap/roaring/go.mod13
-rw-r--r--vendor/github.com/RoaringBitmap/roaring/go.sum55
-rw-r--r--vendor/github.com/RoaringBitmap/roaring/roaringarray.go2
-rw-r--r--vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go282
4 files changed, 289 insertions, 63 deletions
diff --git a/vendor/github.com/RoaringBitmap/roaring/go.mod b/vendor/github.com/RoaringBitmap/roaring/go.mod
index 2a31b3ccc5..88f2e925e7 100644
--- a/vendor/github.com/RoaringBitmap/roaring/go.mod
+++ b/vendor/github.com/RoaringBitmap/roaring/go.mod
@@ -3,18 +3,9 @@ module github.com/RoaringBitmap/roaring
go 1.14
require (
+ github.com/RoaringBitmap/gocroaring v0.4.0
+ github.com/RoaringBitmap/real-roaring-datasets v0.0.0-20190726190000-eb7c87156f76 // indirect
github.com/bits-and-blooms/bitset v1.2.0
- github.com/dvyukov/go-fuzz v0.0.0-20210429054444-fca39067bc72 // indirect
- github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
- github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2
- github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 // indirect
- github.com/golang/snappy v0.0.1 // indirect
- github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 // indirect
- github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/mschoch/smat v0.2.0
- github.com/philhofer/fwd v1.0.0 // indirect
- github.com/stephens2424/writerset v1.0.2 // indirect
github.com/stretchr/testify v1.4.0
- golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
- golang.org/x/tools v0.0.0-20200928182047-19e03678916f // indirect
)
diff --git a/vendor/github.com/RoaringBitmap/roaring/go.sum b/vendor/github.com/RoaringBitmap/roaring/go.sum
index 85373d358f..a6459b8541 100644
--- a/vendor/github.com/RoaringBitmap/roaring/go.sum
+++ b/vendor/github.com/RoaringBitmap/roaring/go.sum
@@ -1,65 +1,18 @@
-github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
+github.com/RoaringBitmap/gocroaring v0.4.0 h1:5nufXUgWpBEUNEJXw7926YAA58ZAQRpWPrQV1xCoSjc=
+github.com/RoaringBitmap/gocroaring v0.4.0/go.mod h1:NieMwz7ZqwU2DD73/vvYwv7r4eWBKuPVSXZIpsaMwCI=
+github.com/RoaringBitmap/real-roaring-datasets v0.0.0-20190726190000-eb7c87156f76 h1:ZYlhPbqQFU+AHfgtCdHGDTtRW1a8geZyiE8c6Q+Sl1s=
+github.com/RoaringBitmap/real-roaring-datasets v0.0.0-20190726190000-eb7c87156f76/go.mod h1:oM0MHmQ3nDsq609SS36p+oYbRi16+oVvU2Bw4Ipv0SE=
github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dvyukov/go-fuzz v0.0.0-20210429054444-fca39067bc72 h1:XiR1YwcWcRFzxjAhWK29HQL4nocj0QWJjpeRi/YASV0=
-github.com/dvyukov/go-fuzz v0.0.0-20210429054444-fca39067bc72/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
-github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
-github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
-github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2 h1:Ujru1hufTHVb++eG6OuNDKMxZnGIvF6o/u8q/8h2+I4=
-github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
-github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
-github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
-github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
-github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw=
-github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae h1:VeRdUYdCw49yizlSbMEn2SZ+gT+3IUKx8BqxyQdz+BY=
-github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
-github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
-github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
-github.com/stephens2424/writerset v1.0.2 h1:znRLgU6g8RS5euYRcy004XeE4W+Tu44kALzy7ghPif8=
-github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc=
-github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200928182047-19e03678916f h1:VwGa2Wf+rHGIxvsssCkUNIyFv8jQY0VCBCNWtikoWq0=
-golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
diff --git a/vendor/github.com/RoaringBitmap/roaring/roaringarray.go b/vendor/github.com/RoaringBitmap/roaring/roaringarray.go
index 6aff57806a..f7b7d732bf 100644
--- a/vendor/github.com/RoaringBitmap/roaring/roaringarray.go
+++ b/vendor/github.com/RoaringBitmap/roaring/roaringarray.go
@@ -569,7 +569,7 @@ func (ra *roaringArray) readFrom(stream internal.ByteInput, cookieHeader ...byte
var isRunBitmap []byte
if cookie&0x0000FFFF == serialCookie {
- size = uint32(uint16(cookie>>16) + 1)
+ size = uint32(cookie>>16 + 1)
// create is-run-container bitmap
isRunBitmapSize := (int(size) + 7) / 8
isRunBitmap, err = stream.Next(isRunBitmapSize)
diff --git a/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go b/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go
index 82edeb8982..18a563e8d6 100644
--- a/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go
+++ b/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go
@@ -3,6 +3,7 @@
package roaring
import (
+ "encoding/binary"
"errors"
"io"
"reflect"
@@ -132,3 +133,284 @@ func byteSliceAsInterval16Slice(slice []byte) (result []interval16) {
// return result
return
}
+
+// FromBuffer creates a bitmap from its serialized version stored in buffer.
+// It uses CRoaring's frozen bitmap format.
+//
+// The format specification is available here:
+// https://github.com/RoaringBitmap/CRoaring/blob/2c867e9f9c9e2a3a7032791f94c4c7ae3013f6e0/src/roaring.c#L2756-L2783
+//
+// The provided byte array (buf) is expected to be a constant.
+// The function makes the best effort attempt not to copy data.
+// Only little endian is supported. The function will err if it detects a big
+// endian serialized file.
+// You should take care not to modify buff as it will likely result in
+// unexpected program behavior.
+// If said buffer comes from a memory map, it's advisable to give it read
+// only permissions, either at creation or by calling Mprotect from the
+// golang.org/x/sys/unix package.
+//
+// Resulting bitmaps are effectively immutable in the following sense:
+// a copy-on-write marker is used so that when you modify the resulting
+// bitmap, copies of selected data (containers) are made.
+// You should *not* change the copy-on-write status of the resulting
+// bitmaps (SetCopyOnWrite).
+//
+// If buf becomes unavailable, then a bitmap created with
+// FromBuffer would be effectively broken. Furthermore, any
+// bitmap derived from this bitmap (e.g., via Or, And) might
+// also be broken. Thus, before making buf unavailable, you should
+// call CloneCopyOnWriteContainers on all such bitmaps.
+//
+func (rb *Bitmap) FrozenView(buf []byte) error {
+ return rb.highlowcontainer.frozenView(buf)
+}
+
+/* Verbatim specification from CRoaring.
+ *
+ * FROZEN SERIALIZATION FORMAT DESCRIPTION
+ *
+ * -- (beginning must be aligned by 32 bytes) --
+ * <bitset_data> uint64_t[BITSET_CONTAINER_SIZE_IN_WORDS * num_bitset_containers]
+ * <run_data> rle16_t[total number of rle elements in all run containers]
+ * <array_data> uint16_t[total number of array elements in all array containers]
+ * <keys> uint16_t[num_containers]
+ * <counts> uint16_t[num_containers]
+ * <typecodes> uint8_t[num_containers]
+ * <header> uint32_t
+ *
+ * <header> is a 4-byte value which is a bit union of FROZEN_COOKIE (15 bits)
+ * and the number of containers (17 bits).
+ *
+ * <counts> stores number of elements for every container.
+ * Its meaning depends on container type.
+ * For array and bitset containers, this value is the container cardinality minus one.
+ * For run container, it is the number of rle_t elements (n_runs).
+ *
+ * <bitset_data>,<array_data>,<run_data> are flat arrays of elements of
+ * all containers of respective type.
+ *
+ * <*_data> and <keys> are kept close together because they are not accessed
+ * during deserilization. This may reduce IO in case of large mmaped bitmaps.
+ * All members have their native alignments during deserilization except <header>,
+ * which is not guaranteed to be aligned by 4 bytes.
+ */
+const FROZEN_COOKIE = 13766
+
+var (
+ FrozenBitmapInvalidCookie = errors.New("header does not contain the FROZEN_COOKIE")
+ FrozenBitmapBigEndian = errors.New("loading big endian frozen bitmaps is not supported")
+ FrozenBitmapIncomplete = errors.New("input buffer too small to contain a frozen bitmap")
+ FrozenBitmapOverpopulated = errors.New("too many containers")
+ FrozenBitmapUnexpectedData = errors.New("spurious data in input")
+ FrozenBitmapInvalidTypecode = errors.New("unrecognized typecode")
+ FrozenBitmapBufferTooSmall = errors.New("buffer too small")
+)
+
+func (ra *roaringArray) frozenView(buf []byte) error {
+ if len(buf) < 4 {
+ return FrozenBitmapIncomplete
+ }
+
+ headerBE := binary.BigEndian.Uint32(buf[len(buf)-4:])
+ if headerBE & 0x7fff == FROZEN_COOKIE {
+ return FrozenBitmapBigEndian
+ }
+
+ header := binary.LittleEndian.Uint32(buf[len(buf)-4:])
+ buf = buf[:len(buf)-4]
+
+ if header & 0x7fff != FROZEN_COOKIE {
+ return FrozenBitmapInvalidCookie
+ }
+
+ nCont := int(header >> 15)
+ if nCont > (1 << 16) {
+ return FrozenBitmapOverpopulated
+ }
+
+ // 1 byte per type, 2 bytes per key, 2 bytes per count.
+ if len(buf) < 5*nCont {
+ return FrozenBitmapIncomplete
+ }
+
+ types := buf[len(buf)-nCont:]
+ buf = buf[:len(buf)-nCont]
+
+ counts := byteSliceAsUint16Slice(buf[len(buf)-2*nCont:])
+ buf = buf[:len(buf)-2*nCont]
+
+ keys := byteSliceAsUint16Slice(buf[len(buf)-2*nCont:])
+ buf = buf[:len(buf)-2*nCont]
+
+ nBitmap, nArray, nRun := uint64(0), uint64(0), uint64(0)
+ nArrayEl, nRunEl := uint64(0), uint64(0)
+ for i, t := range types {
+ switch (t) {
+ case 1:
+ nBitmap++
+ case 2:
+ nArray++
+ nArrayEl += uint64(counts[i])+1
+ case 3:
+ nRun++
+ nRunEl += uint64(counts[i])
+ default:
+ return FrozenBitmapInvalidTypecode
+ }
+ }
+
+ if uint64(len(buf)) < (1 << 13)*nBitmap + 4*nRunEl + 2*nArrayEl {
+ return FrozenBitmapIncomplete
+ }
+
+ bitsetsArena := byteSliceAsUint64Slice(buf[:(1 << 13)*nBitmap])
+ buf = buf[(1 << 13)*nBitmap:]
+
+ runsArena := byteSliceAsInterval16Slice(buf[:4*nRunEl])
+ buf = buf[4*nRunEl:]
+
+ arraysArena := byteSliceAsUint16Slice(buf[:2*nArrayEl])
+ buf = buf[2*nArrayEl:]
+
+ if len(buf) != 0 {
+ return FrozenBitmapUnexpectedData
+ }
+
+ // TODO: maybe arena_alloc all this.
+ containers := make([]container, nCont)
+ bitsets := make([]bitmapContainer, nBitmap)
+ arrays := make([]arrayContainer, nArray)
+ runs := make([]runContainer16, nRun)
+ needCOW := make([]bool, nCont)
+
+ iBitset, iArray, iRun := uint64(0), uint64(0), uint64(0)
+ for i, t := range types {
+ needCOW[i] = true
+
+ switch (t) {
+ case 1:
+ containers[i] = &bitsets[iBitset]
+ bitsets[iBitset].cardinality = int(counts[i])+1
+ bitsets[iBitset].bitmap = bitsetsArena[:1024]
+ bitsetsArena = bitsetsArena[1024:]
+ iBitset++
+ case 2:
+ containers[i] = &arrays[iArray]
+ arrays[iArray].content = arraysArena[:counts[i]+1]
+ arraysArena = arraysArena[counts[i]+1:]
+ iArray++
+ case 3:
+ containers[i] = &runs[iRun]
+ runs[iRun].iv = runsArena[:counts[i]]
+ runsArena = runsArena[counts[i]:]
+ iRun++
+ }
+ }
+
+ // Not consuming the full input is a bug.
+ if iBitset != nBitmap || len(bitsetsArena) != 0 ||
+ iArray != nArray || len(arraysArena) != 0 ||
+ iRun != nRun || len(runsArena) != 0 {
+ panic("we missed something")
+ }
+
+ ra.keys = keys
+ ra.containers = containers
+ ra.needCopyOnWrite = needCOW
+ ra.copyOnWrite = true
+
+ return nil
+}
+
+func (bm *Bitmap) GetFrozenSizeInBytes() uint64 {
+ nBits, nArrayEl, nRunEl := uint64(0), uint64(0), uint64(0)
+ for _, c := range bm.highlowcontainer.containers {
+ switch v := c.(type) {
+ case *bitmapContainer:
+ nBits++
+ case *arrayContainer:
+ nArrayEl += uint64(len(v.content))
+ case *runContainer16:
+ nRunEl += uint64(len(v.iv))
+ }
+ }
+ return 4 + 5*uint64(len(bm.highlowcontainer.containers)) +
+ (nBits << 13) + 2*nArrayEl + 4*nRunEl
+}
+
+func (bm *Bitmap) Freeze() ([]byte, error) {
+ sz := bm.GetFrozenSizeInBytes()
+ buf := make([]byte, sz)
+ _, err := bm.FreezeTo(buf)
+ return buf, err
+}
+
+func (bm *Bitmap) FreezeTo(buf []byte) (int, error) {
+ containers := bm.highlowcontainer.containers
+ nCont := len(containers)
+
+ nBits, nArrayEl, nRunEl := 0, 0, 0
+ for _, c := range containers {
+ switch v := c.(type) {
+ case *bitmapContainer:
+ nBits++
+ case *arrayContainer:
+ nArrayEl += len(v.content)
+ case *runContainer16:
+ nRunEl += len(v.iv)
+ }
+ }
+
+ serialSize := 4 + 5*nCont + (1 << 13)*nBits + 4*nRunEl + 2*nArrayEl
+ if len(buf) < serialSize {
+ return 0, FrozenBitmapBufferTooSmall
+ }
+
+ bitsArena := byteSliceAsUint64Slice(buf[:(1 << 13)*nBits])
+ buf = buf[(1 << 13)*nBits:]
+
+ runsArena := byteSliceAsInterval16Slice(buf[:4*nRunEl])
+ buf = buf[4*nRunEl:]
+
+ arraysArena := byteSliceAsUint16Slice(buf[:2*nArrayEl])
+ buf = buf[2*nArrayEl:]
+
+ keys := byteSliceAsUint16Slice(buf[:2*nCont])
+ buf = buf[2*nCont:]
+
+ counts := byteSliceAsUint16Slice(buf[:2*nCont])
+ buf = buf[2*nCont:]
+
+ types := buf[:nCont]
+ buf = buf[nCont:]
+
+ header := uint32(FROZEN_COOKIE|(nCont << 15))
+ binary.LittleEndian.PutUint32(buf[:4], header)
+
+ copy(keys, bm.highlowcontainer.keys[:])
+
+ for i, c := range containers {
+ switch v := c.(type) {
+ case *bitmapContainer:
+ copy(bitsArena, v.bitmap)
+ bitsArena = bitsArena[1024:]
+ counts[i] = uint16(v.cardinality-1)
+ types[i] = 1
+ case *arrayContainer:
+ copy(arraysArena, v.content)
+ arraysArena = arraysArena[len(v.content):]
+ elems := len(v.content)
+ counts[i] = uint16(elems)-1
+ types[i] = 2
+ case *runContainer16:
+ copy(runsArena, v.iv)
+ runs := len(v.iv)
+ runsArena = runsArena[runs:]
+ counts[i] = uint16(runs)
+ types[i] = 3
+ }
+ }
+
+ return serialSize, nil
+}