diff --git a/Cargo.lock b/Cargo.lock index 3fb9e103..b4852337 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arrayvec" @@ -16,9 +16,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "benchmarks" @@ -74,15 +74,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -124,9 +118,9 @@ dependencies = [ [[package]] name = "candid" -version = "0.10.3" +version = "0.10.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "182543fbc03b4ad0bfc384e6b68346e0b0aad0b11d075b71b4fcaa5d07f8862c" +checksum = "6c30ee7f886f296b6422c0ff017e89dd4f831521dfdcc76f3f71aae1ce817222" dependencies = [ "anyhow", "binread", @@ -147,23 +141,23 @@ dependencies = [ [[package]] name = "candid_derive" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970c220da8aa2fa6f7ef5dbbf3ea5b620a59eb3ac107cfb95ae8c6eebdfb7a08" +checksum = "3de398570c386726e7a59d9887b68763c481477f9a043fb998a2e09d428df1a9" dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.87", ] [[package]] name = "cc" -version = "1.0.83" +version = "1.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" dependencies = [ - "libc", + "shlex", ] [[package]] @@ -174,18 +168,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -202,9 +196,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "digest" @@ -218,25 +212,25 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.0.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fnv" @@ -256,9 +250,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -273,9 +267,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "ic-cdk" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3d204af0b11c45715169c997858edb58fa8407d08f4fae78a6b415dd39a362" +checksum = "0e908da565d9e304e83732500069ebb959e3d2cad80f894889ea37207112c7a0" dependencies = [ "candid", "ic-cdk-macros", @@ -302,6 +296,7 @@ dependencies = [ name = "ic-stable-structures" version = "0.6.5" dependencies = [ + "bit-vec", "canbench-rs", "candid", "hex", @@ -335,9 +330,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -347,21 +342,21 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "maplit" @@ -371,11 +366,10 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", "serde", @@ -383,35 +377,43 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", ] +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "pretty" @@ -426,22 +428,22 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.2", + "bitflags", "lazy_static", "num-traits", "rand", @@ -455,9 +457,9 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205" dependencies = [ "cc", ] @@ -470,9 +472,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -516,39 +518,30 @@ dependencies = [ "rand_core", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ - "bitflags 2.4.2", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rusty-fork" @@ -564,31 +557,31 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.195" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.87", ] [[package]] @@ -613,17 +606,23 @@ dependencies = [ "digest", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "stacker" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" dependencies = [ "cc", "cfg-if", "libc", "psm", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -635,7 +634,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.48", + "syn 2.0.87", ] [[package]] @@ -646,7 +645,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.87", ] [[package]] @@ -662,9 +661,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -673,15 +672,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -693,27 +692,27 @@ dependencies = [ "proc-macro2", "quote", "structmeta", - "syn 2.0.48", + "syn 2.0.87", ] [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.87", ] [[package]] @@ -742,21 +741,21 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" @@ -774,45 +773,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-targets", ] -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -821,42 +808,69 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] diff --git a/Cargo.toml b/Cargo.toml index 32252f05..441ea38f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ include = ["src", "Cargo.toml", "LICENSE", "README.md"] repository = "https://github.com/dfinity/stable-structures" [dependencies] +bit-vec = "0.6" ic_principal = { version = "0.1.1", default-features = false } # An optional dependency to benchmark parts of the code. canbench-rs = { version = "0.1.7", optional = true } diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 54321b4e..fafe0b98 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arrayvec" @@ -27,9 +27,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "basic_example" @@ -64,6 +64,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "block-buffer" version = "0.10.4" @@ -115,16 +121,16 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.87", ] [[package]] name = "cc" -version = "1.0.83" +version = "1.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" dependencies = [ - "libc", + "shlex", ] [[package]] @@ -135,9 +141,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -146,15 +152,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", @@ -172,22 +178,28 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -211,9 +223,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "digest" @@ -227,9 +239,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "equivalent" @@ -249,15 +261,19 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "hex" @@ -267,9 +283,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "ic-cdk" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d4c0b932bf454d5d60e61e13c3c944972fcfd74dc82b9ed5c8b0a75979cf50" +checksum = "6760cfb714f1ef4bd7a8d3d848306b70949c147e16b29b751965f869c0e88730" dependencies = [ "candid", "ic-cdk-macros", @@ -296,6 +312,7 @@ dependencies = [ name = "ic-stable-structures" version = "0.6.5" dependencies = [ + "bit-vec", "ic_principal", ] @@ -313,9 +330,9 @@ checksum = "1762deb6f7c8d8c2bdee4b6c5a47b60195b74e9b5280faa5ba29692f8e17429c" [[package]] name = "indexmap" -version = "2.1.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", @@ -323,9 +340,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -335,23 +352,22 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", "serde", @@ -359,19 +375,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -394,20 +409,20 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.87", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pretty" @@ -432,18 +447,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] [[package]] name = "psm" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205" dependencies = [ "cc", ] @@ -462,46 +477,46 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.87", ] [[package]] @@ -526,17 +541,23 @@ dependencies = [ "digest", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "stacker" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" dependencies = [ "cc", "cfg-if", "libc", "psm", - "winapi", + "windows-sys", ] [[package]] @@ -552,9 +573,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -574,38 +595,38 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.87", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" @@ -632,15 +653,15 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "vecs_and_strings" @@ -654,46 +675,97 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "winapi" -version = "0.3.9" +name = "winapi-util" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-sys", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] [[package]] -name = "winapi-util" -version = "0.1.6" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "winapi", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.28" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] diff --git a/src/memory_manager.rs b/src/memory_manager.rs index a84075be..18638a12 100644 --- a/src/memory_manager.rs +++ b/src/memory_manager.rs @@ -40,18 +40,21 @@ //! memory_1.read(0, &mut bytes); //! assert_eq!(bytes, vec![4, 5, 6]); //! ``` +use bit_vec::BitVec; + use crate::{ read_struct, types::{Address, Bytes}, write, write_struct, Memory, WASM_PAGE_SIZE, }; -use std::cell::RefCell; use std::cmp::min; use std::collections::BTreeMap; use std::rc::Rc; +use std::{cell::RefCell, collections::BTreeSet}; const MAGIC: &[u8; 3] = b"MGR"; -const LAYOUT_VERSION: u8 = 1; +const LAYOUT_VERSION_V1: u8 = 1; +const LAYOUT_VERSION_V2: u8 = 2; // The maximum number of memories that can be created. const MAX_NUM_MEMORIES: u8 = 255; @@ -72,6 +75,9 @@ const BUCKETS_OFFSET_IN_BYTES: u64 = BUCKETS_OFFSET_IN_PAGES * WASM_PAGE_SIZE; // Reserved bytes in the header for future extensions. const HEADER_RESERVED_BYTES: usize = 32; +// Size of the bucket ID in the header. +const BUCKET_ID_LEN_IN_BITS: usize = 15; + /// A memory manager simulates multiple memories within a single memory. /// /// The memory manager can return up to 255 unique instances of [`VirtualMemory`], and each can be @@ -127,6 +133,58 @@ const HEADER_RESERVED_BYTES: usize = 32; /// ... /// -------------------------------------------------- <- Page ((MAX_NUM_BUCKETS - 1) * N + 1) /// Bucket MAX_NUM_BUCKETS ↕ N pages +/// +/// # V2 layout +/// +/// ```text +/// -------------------------------------------------- <- Address 0 +/// Magic "MGR" ↕ 3 bytes +/// -------------------------------------------------- +/// Layout version ↕ 1 byte +/// -------------------------------------------------- +/// Number of allocated buckets ↕ 2 bytes +/// -------------------------------------------------- +/// Bucket size (in pages) = N ↕ 2 bytes +/// -------------------------------------------------- +/// Reserved space ↕ 32 bytes +/// -------------------------------------------------- +/// Size of memory 0 (in pages) ↕ 8 bytes +/// -------------------------------------------------- +/// Size of memory 1 (in pages) ↕ 8 bytes +/// -------------------------------------------------- +/// ... +/// -------------------------------------------------- +/// Size of memory 254 (in pages) ↕ 8 bytes +/// -------------------------------------------------- <- IDs of buckets +/// Bucket 1 belonging to memory 0 ↕ 15 bits +/// -------------------------------------------------- +/// Bucket 2 belonging to memory 0 ↕ 15 bits +/// -------------------------------------------------- +/// ... +/// -------------------------------------------------- +/// Bucket 1 belonging to memory 1 ↕ 15 bits +/// -------------------------------------------------- +/// Bucket 2 belonging to memory 1 ↕ 15 bits +/// -------------------------------------------------- +/// ... +/// -------------------------------------------------- +/// ... +/// --------------------------------------------------- +/// Bucket 1 belonging to memory 254 ↕ 15 bits +/// -------------------------------------------------- +/// Bucket 2 belonging to memory 254 ↕ 15 bits +/// -------------------------------------------------- +/// ... +/// -------------------------------------------------- +/// Unallocated space ↕ 2'016 bytes +/// -------------------------------------------------- <- Buckets (Page 1) +/// Bucket 1 ↕ N pages +/// -------------------------------------------------- <- Page N + 1 +/// Bucket 2 ↕ N pages +/// -------------------------------------------------- +/// ... +/// -------------------------------------------------- <- Page ((MAX_NUM_BUCKETS - 1) * N + 1) +/// Bucket MAX_NUM_BUCKETS ↕ N pages /// ``` pub struct MemoryManager { inner: Rc>>, @@ -148,6 +206,16 @@ impl MemoryManager { } } + #[cfg(test)] + pub fn init_with_bucket_size_v1(memory: M, bucket_size_in_pages: u16) -> Self { + Self { + inner: Rc::new(RefCell::new(MemoryManagerInner::init_v1( + memory, + bucket_size_in_pages, + ))), + } + } + /// Returns the memory associated with the given ID. pub fn get(&self, id: MemoryId) -> VirtualMemory { VirtualMemory { @@ -164,6 +232,13 @@ impl MemoryManager { pub fn into_memory(self) -> Option { Rc::into_inner(self.inner).map(|inner| inner.into_inner().into_memory()) } + + /// Frees the specified memory. + /// Note that the underlying physical memory doesn't shrink, but the space previously + /// occupied by the given memory will be reused. + pub fn free(&mut self, id: MemoryId) { + self.inner.borrow_mut().free(id); + } } #[repr(C, packed)] @@ -229,6 +304,10 @@ struct MemoryManagerInner { // A map mapping each managed memory to the bucket ids that are allocated to it. memory_buckets: BTreeMap>, + + // Tracks the buckets that were freed to be reused in future calls to `grow`. + // NOTE: A BTreeSet is used so that bucket IDs are maintained in sorted order. + freed_buckets: BTreeSet, } impl MemoryManagerInner { @@ -257,10 +336,46 @@ impl MemoryManagerInner { memory_sizes_in_pages: [0; MAX_NUM_MEMORIES as usize], memory_buckets: BTreeMap::new(), bucket_size_in_pages, + freed_buckets: BTreeSet::new(), }; mem_mgr.save_header(); + mem_mgr + } + + #[cfg(test)] + fn init_v1(memory: M, bucket_size_in_pages: u16) -> Self { + if memory.size() == 0 { + // Memory is empty. Create a new map. + return Self::new(memory, bucket_size_in_pages); + } + + // Check if the magic in the memory corresponds to this object. + let mut dst = vec![0; 3]; + memory.read(0, &mut dst); + if dst != MAGIC { + // No memory manager found. Create a new instance. + MemoryManagerInner::new_v1(memory, bucket_size_in_pages) + } else { + // The memory already contains a memory manager. Load it. + MemoryManagerInner::load(memory) + } + } + + #[cfg(test)] + fn new_v1(memory: M, bucket_size_in_pages: u16) -> Self { + let mem_mgr = Self { + memory, + allocated_buckets: 0, + memory_sizes_in_pages: [0; MAX_NUM_MEMORIES as usize], + memory_buckets: BTreeMap::new(), + bucket_size_in_pages, + freed_buckets: BTreeSet::new(), + }; + + mem_mgr.save_header_v1(); + // Mark all the buckets as unallocated. write( &mem_mgr.memory, @@ -271,16 +386,11 @@ impl MemoryManagerInner { mem_mgr } - fn load(memory: M) -> Self { - // Read the header from memory. - let header: Header = read_struct(Address::from(0), &memory); - assert_eq!(&header.magic, MAGIC, "Bad magic."); - assert_eq!(header.version, LAYOUT_VERSION, "Unsupported version."); - + fn load_layout_v1(memory: M, header: Header) -> Self { let mut buckets = vec![0; MAX_NUM_BUCKETS as usize]; memory.read(bucket_allocations_address(BucketId(0)).get(), &mut buckets); - let mut memory_buckets = BTreeMap::new(); + for (bucket_idx, memory) in buckets.into_iter().enumerate() { if memory != UNALLOCATED_BUCKET_MARKER { memory_buckets @@ -296,13 +406,88 @@ impl MemoryManagerInner { bucket_size_in_pages: header.bucket_size_in_pages, memory_sizes_in_pages: header.memory_sizes_in_pages, memory_buckets, + freed_buckets: BTreeSet::new(), + } + } + + fn load_layout_v2(memory: M, header: Header) -> Self { + let mut memory_size_in_buckets = vec![]; + let mut number_of_used_buckets = 0; + + // Translate memory sizes expressed in pages to sizes expressed in buckets. + for memory_size_in_pages in header.memory_sizes_in_pages.into_iter() { + let size_in_buckets = memory_size_in_pages.div_ceil(header.bucket_size_in_pages as u64); + memory_size_in_buckets.push(size_in_buckets); + number_of_used_buckets += size_in_buckets; + } + + // Load the buckets. + let buckets = { + const BYTE_SIZE_IN_BITS: usize = 8; + let buckets_index_size_in_bytes: usize = (number_of_used_buckets as usize + * BUCKET_ID_LEN_IN_BITS) + .div_ceil(BYTE_SIZE_IN_BITS); + + let mut buckets = vec![0; buckets_index_size_in_bytes]; + memory.read(bucket_indexes_offset().get(), &mut buckets); + + bytes_to_bucket_indexes(&buckets) + }; + + // Map of all memories with their assigned buckets. + let mut memory_buckets = BTreeMap::new(); + + // The last bucket that's accessed. + let mut max_bucket_id: u16 = 0; + + let mut bucket_idx: usize = 0; + + // Assign buckets to the memories they are part of. + for (memory, size_in_buckets) in memory_size_in_buckets.into_iter().enumerate() { + let mut vec_buckets = vec![]; + for _ in 0..size_in_buckets { + let bucket = buckets[bucket_idx]; + max_bucket_id = std::cmp::max(bucket.0, max_bucket_id); + vec_buckets.push(bucket); + bucket_idx += 1; + } + memory_buckets + .entry(MemoryId(memory as u8)) + .or_insert(vec_buckets); + } + + // Set of all buckets with ID smaller than 'max_bucket_id' which were allocated and freed. + let mut freed_buckets: BTreeSet = (0..max_bucket_id).map(BucketId).collect(); + + for id in buckets.iter() { + freed_buckets.remove(id); + } + + Self { + memory, + allocated_buckets: header.num_allocated_buckets, + bucket_size_in_pages: header.bucket_size_in_pages, + memory_sizes_in_pages: header.memory_sizes_in_pages, + memory_buckets, + freed_buckets, + } + } + + fn load(memory: M) -> Self { + // Read the header from memory. + let header: Header = read_struct(Address::from(0), &memory); + assert_eq!(&header.magic, MAGIC, "Bad magic."); + match header.version { + LAYOUT_VERSION_V1 => MemoryManagerInner::load_layout_v1(memory, header), + LAYOUT_VERSION_V2 => MemoryManagerInner::load_layout_v2(memory, header), + _ => panic!("Unsupported version."), } } fn save_header(&self) { let header = Header { magic: *MAGIC, - version: LAYOUT_VERSION, + version: LAYOUT_VERSION_V2, num_allocated_buckets: self.allocated_buckets, bucket_size_in_pages: self.bucket_size_in_pages, _reserved: [0; HEADER_RESERVED_BYTES], @@ -326,28 +511,28 @@ impl MemoryManagerInner { let required_buckets = self.num_buckets_needed(new_size); let new_buckets_needed = required_buckets - current_buckets; - if new_buckets_needed + self.allocated_buckets as u64 > MAX_NUM_BUCKETS { + if new_buckets_needed + self.allocated_buckets as u64 - self.freed_buckets.len() as u64 + > MAX_NUM_BUCKETS + { // Exceeded the memory that can be managed. return -1; } // Allocate new buckets as needed. for _ in 0..new_buckets_needed { - let new_bucket_id = BucketId(self.allocated_buckets); + let new_bucket_id = match self.freed_buckets.pop_first() { + Some(t) => t, + None => { + let new_id = self.allocated_buckets; + self.allocated_buckets += 1; + BucketId(new_id) + } + }; self.memory_buckets .entry(id) .or_default() .push(new_bucket_id); - - // Write in stable store that this bucket belongs to the memory with the provided `id`. - write( - &self.memory, - bucket_allocations_address(new_bucket_id).get(), - &[id.0], - ); - - self.allocated_buckets += 1; } // Grow the underlying memory if necessary. @@ -364,11 +549,35 @@ impl MemoryManagerInner { // Update the memory with the new size. self.memory_sizes_in_pages[id.0 as usize] = new_size; - // Update the header and return the old size. + // Update the header. self.save_header(); + + // Write in stable store that this bucket belongs to the memory with the provided `id`. + write( + &self.memory, + bucket_indexes_offset().get(), + self.get_bucket_ids_in_bytes().as_ref(), + ); + + // Return the old size. old_size as i64 } + fn get_bucket_ids_in_bytes(&self) -> Vec { + let mut bit_vec = BitVec::new(); + for memory in self.memory_buckets.iter() { + for bucket in memory.1 { + let bucket_ind = bucket.0; + // Splits bit_vec returning the slice [1, .., bit_vec.size() - 1]. + // This is precisely what we need since the BucketId can be represented + // using only 15 bits, instead of 16. + let mut bit_vec_temp = BitVec::from_bytes(&bucket_ind.to_be_bytes()).split_off(1); + bit_vec.append(&mut bit_vec_temp); + } + } + bit_vec.to_bytes() + } + fn write(&self, id: MemoryId, offset: u64, src: &[u8]) { if (offset + src.len() as u64) > self.memory_size(id) * WASM_PAGE_SIZE { panic!("{id:?}: write out of bounds"); @@ -433,6 +642,56 @@ impl MemoryManagerInner { pub fn into_memory(self) -> M { self.memory } + + fn free(&mut self, id: MemoryId) { + self.memory_sizes_in_pages[id.0 as usize] = 0; + let buckets = self.memory_buckets.remove(&id); + if let Some(vec_buckets) = buckets { + for bucket in vec_buckets { + self.freed_buckets.insert(bucket); + } + } + // Update the header. + self.save_header(); + + // Write in stable store that no bucket belongs to the memory with the provided `id`. + write( + &self.memory, + bucket_indexes_offset().get(), + self.get_bucket_ids_in_bytes().as_ref(), + ); + } + + #[cfg(test)] + fn save_header_v1(&self) { + let header = Header { + magic: *MAGIC, + version: LAYOUT_VERSION_V1, + num_allocated_buckets: self.allocated_buckets, + bucket_size_in_pages: self.bucket_size_in_pages, + _reserved: [0; HEADER_RESERVED_BYTES], + memory_sizes_in_pages: self.memory_sizes_in_pages, + }; + + write_struct(&header, Address::from(0), &self.memory); + } +} + +fn bytes_to_bucket_indexes(input: &[u8]) -> Vec { + let mut bucket_ids = vec![]; + let bit_vec = BitVec::from_bytes(input); + for bucket_order_number in 0..bit_vec.len() / BUCKET_ID_LEN_IN_BITS { + let mut bucket_id: u16 = 0; + for bucket_id_bit in 0..BUCKET_ID_LEN_IN_BITS { + let next_bit = BUCKET_ID_LEN_IN_BITS * bucket_order_number + bucket_id_bit; + bucket_id <<= 1; + if bit_vec.get(next_bit) == Some(true) { + bucket_id |= 1; + } + } + bucket_ids.push(BucketId(bucket_id)); + } + bucket_ids } struct Segment { @@ -533,13 +792,17 @@ impl MemoryId { } // Referring to a bucket. -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] struct BucketId(u16); fn bucket_allocations_address(id: BucketId) -> Address { Address::from(0) + Header::size() + Bytes::from(id.0) } +fn bucket_indexes_offset() -> Address { + Address::from(0) + Header::size() +} + #[cfg(test)] mod test { use super::*; @@ -867,4 +1130,266 @@ mod test { memory_1.read(0, &mut buf); assert_eq!(buf, vec![2; 1000]); } + + #[test] + fn free_memory_works() { + let mem = make_memory(); + let mut mem_mgr = MemoryManager::init(mem.clone()); + let memory_0 = mem_mgr.get(MemoryId(0)); + let memory_1 = mem_mgr.get(MemoryId(1)); + + // Grow the memory by 1 page. + assert_eq!(memory_0.grow(1), 0); + assert_eq!(mem.size(), BUCKET_SIZE_IN_PAGES + 1); + + // Grow the memory by 1 page. + assert_eq!(memory_1.grow(1), 0); + assert_eq!(mem.size(), 2 * BUCKET_SIZE_IN_PAGES + 1); + + // Grow the memory by BUCKET_SIZE_IN_PAGES more pages, which will cause the underlying + // allocation to increase. + assert_eq!(memory_0.grow(BUCKET_SIZE_IN_PAGES), 1); + assert_eq!(mem.size(), 1 + BUCKET_SIZE_IN_PAGES * 3); + assert_eq!(memory_1.grow(BUCKET_SIZE_IN_PAGES), 1); + assert_eq!(mem.size(), 1 + BUCKET_SIZE_IN_PAGES * 4); + assert_eq!(mem_mgr.get(MemoryId(1)).size(), 1 + BUCKET_SIZE_IN_PAGES); + + // Free Memory ID 1. + mem_mgr.free(MemoryId(1)); + assert_eq!(mem_mgr.get(MemoryId(1)).size(), 0); + assert_eq!(mem.size(), 1 + BUCKET_SIZE_IN_PAGES * 4); + + let memory_2 = mem_mgr.get(MemoryId(2)); + // When growing memory_2, mem.size() should stay the same since + // MemoryManager should use the memory that is freed above. + assert_eq!(memory_2.grow(1), 0); + assert_eq!(mem_mgr.get(MemoryId(2)).size(), 1); + assert_eq!(mem.size(), 1 + BUCKET_SIZE_IN_PAGES * 4); + assert_eq!(memory_2.grow(BUCKET_SIZE_IN_PAGES), 1); + assert_eq!(mem_mgr.get(MemoryId(2)).size(), 1 + BUCKET_SIZE_IN_PAGES); + assert_eq!(mem.size(), 1 + BUCKET_SIZE_IN_PAGES * 4); + + // When trying to grow memory_2 again, we need more pages, + // because we have already used all that is left from Memory ID 1. + assert_ne!(memory_2.grow(BUCKET_SIZE_IN_PAGES), 0); + assert_eq!( + mem_mgr.get(MemoryId(2)).size(), + 1 + 2 * BUCKET_SIZE_IN_PAGES + ); + assert_eq!(mem.size(), 1 + BUCKET_SIZE_IN_PAGES * 5); + } + + #[test] + #[should_panic = "MemoryId(1): read out of bounds"] + fn reading_freed_memory_panics() { + let mem = make_memory(); + let mem_mgr = MemoryManager::init(mem.clone()); + let memory_0 = mem_mgr.get(MemoryId(0)); + let memory_1 = mem_mgr.get(MemoryId(1)); + let memory_2 = mem_mgr.get(MemoryId(2)); + + assert_eq!(memory_0.grow(1), 0); + assert_eq!(memory_1.grow(1), 0); + assert_eq!(memory_2.grow(1), 0); + + memory_0.write(0, &[1, 2, 3]); + memory_1.write(0, &[4, 5, 6]); + memory_2.write(0, &[7, 8, 9]); + + let mut mem_mgr = MemoryManager::init(mem); + let memory_0 = mem_mgr.get(MemoryId(0)); + let memory_1 = mem_mgr.get(MemoryId(1)); + let memory_2 = mem_mgr.get(MemoryId(2)); + + let mut bytes = vec![0; 3]; + // Check that data is correctly reinitialized. + memory_0.read(0, &mut bytes); + assert_eq!(bytes, vec![1, 2, 3]); + + memory_1.read(0, &mut bytes); + assert_eq!(bytes, vec![4, 5, 6]); + + memory_2.read(0, &mut bytes); + assert_eq!(bytes, vec![7, 8, 9]); + + // Free MemoryId 1. + mem_mgr.free(MemoryId(1)); + + // Check that data of MemoryId 0 and 2 is correctly reinitialized. + memory_0.read(0, &mut bytes); + assert_eq!(bytes, vec![1, 2, 3]); + + memory_2.read(0, &mut bytes); + assert_eq!(bytes, vec![7, 8, 9]); + + // Check that date of MemoryId 1 is freed. + assert_eq!(memory_1.size(), 0); + memory_1.read(0, &mut bytes); + } + + #[test] + fn freeing_already_free_memory() { + let mut mem_mgr = MemoryManager::init(make_memory()); + let memory_0 = mem_mgr.get(MemoryId(0)); + + assert_eq!(memory_0.grow(1), 0); + + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 1); + + mem_mgr.free(MemoryId(0)); + + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 0); + + mem_mgr.free(MemoryId(0)); + + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 0); + } + + #[test] + fn grow_memory_after_freeing_it() { + let mut mem_mgr = MemoryManager::init(make_memory()); + let memory_0 = mem_mgr.get(MemoryId(0)); + + // grow and write to memory + assert_eq!(memory_0.grow(1), 0); + memory_0.write(0, &[7, 1, 5]); + + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 1); + + let mut bytes = vec![0; 3]; + + // read from memory + memory_0.read(0, &mut bytes); + assert_eq!(bytes, &[7, 1, 5]); + + // free memory + mem_mgr.free(MemoryId(0)); + + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 0); + + // grow memory + assert_eq!(memory_0.grow(1), 0); + + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 1); + + // check that old bucket is reassign to the memory + memory_0.read(0, &mut bytes); + assert_eq!(bytes, &[7, 1, 5]); + + // try growing once more + assert_eq!(memory_0.grow(1), 1); + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 2); + } + + #[test] + fn test_freed_buckets_assignment_order() { + let mut mem_mgr = MemoryManager::init(make_memory()); + let memory_a: VirtualMemory>>> = mem_mgr.get(MemoryId(0)); + let memory_b: VirtualMemory>>> = mem_mgr.get(MemoryId(1)); + + // grow and write to memory + assert_eq!(memory_a.grow(1), 0); + assert_eq!(memory_b.grow(1), 0); + memory_a.write(0, &[7, 1, 5]); + memory_b.write(0, &[9, 4, 8]); + + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 1); + assert_eq!(mem_mgr.get(MemoryId(1)).size(), 1); + + let mut bytes = vec![0; 3]; + + // free memory + mem_mgr.free(MemoryId(0)); + mem_mgr.free(MemoryId(1)); + + assert_eq!(mem_mgr.get(MemoryId(0)).size(), 0); + assert_eq!(mem_mgr.get(MemoryId(1)).size(), 0); + + let memory_c: VirtualMemory>>> = mem_mgr.get(MemoryId(2)); + let memory_d: VirtualMemory>>> = mem_mgr.get(MemoryId(3)); + + // grow memory + assert_eq!(memory_c.grow(1), 0); + assert_eq!(memory_d.grow(1), 0); + + assert_eq!(mem_mgr.get(MemoryId(2)).size(), 1); + assert_eq!(mem_mgr.get(MemoryId(3)).size(), 1); + + // check that old bucket is reassign to the memory + memory_c.read(0, &mut bytes); + assert_eq!(bytes, &[7, 1, 5]); + + // check that old bucket is reassign to the memory + memory_d.read(0, &mut bytes); + assert_eq!(bytes, &[9, 4, 8]); + } + + #[test] + fn free_memory_that_was_not_used() { + let mut mem_mgr = MemoryManager::init(make_memory()); + let memory_0 = mem_mgr.get(MemoryId(0)); + assert_eq!(memory_0.grow(1), 0); + + mem_mgr.free(MemoryId(5)); + } + + #[test] + fn freed_memories_are_tracked() { + let mem = make_memory(); + let mut mem_mgr = MemoryManager::init(mem.clone()); + mem_mgr.get(MemoryId(0)).grow(1); + mem_mgr.get(MemoryId(1)).grow(1); + mem_mgr.get(MemoryId(2)).grow(1); + mem_mgr.get(MemoryId(3)).grow(1); + mem_mgr.get(MemoryId(4)).grow(1); + + mem_mgr.free(MemoryId(0)); + mem_mgr.free(MemoryId(2)); + mem_mgr.free(MemoryId(4)); + + let mem_mgr = MemoryManager::init(mem); + // Only Memory 0 and 2 buckets should be counted as freed_buckets. + // The bucket belonging to Memory 4 should not be counted as + // freed because it has the biggest Bucket ID of all allocated + // buckets hence it should become part of unallocated buckets. + assert_eq!( + mem_mgr.inner.borrow().freed_buckets, + maplit::btreeset! { BucketId(0), BucketId(2) } + ); + } + + #[test] + fn upgrade_from_v1_to_v2() { + let mem = make_memory(); + // Initialize with layout v1. + let mem_mgr = MemoryManager::init_with_bucket_size_v1(mem.clone(), 1); // very small bucket size. + + let memories_v1: Vec<_> = (0..MAX_NUM_MEMORIES) + .map(|id| mem_mgr.get(MemoryId(id))) + .collect(); + + proptest!(|( + num_memories in 0..255usize, + data in proptest::collection::vec(0..u8::MAX, 0..2*WASM_PAGE_SIZE as usize), + offset in 0..10*WASM_PAGE_SIZE + )| { + for memory_v1 in memories_v1.iter().take(num_memories) { + // Write a random blob into the memory, growing the memory as it needs to. + write(memory_v1, offset, &data); + } + + // Load layout v1 and convert it to layout v2. + let mem_mgr_v2 = MemoryManager::init_with_bucket_size(mem.clone(), 1); + let memories_v2: Vec<_> = (0..MAX_NUM_MEMORIES) + .map(|id| mem_mgr_v2.get(MemoryId(id))) + .collect(); + + for memory_v2 in memories_v2.iter().take(num_memories) { + // Verify the blob can be read back. + let mut bytes = vec![0; data.len()]; + memory_v2.read(offset, &mut bytes); + assert_eq!(bytes, data); + } + }); + } }