opendal 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +89 -56
  3. data/Cargo.toml +1 -1
  4. data/DEPENDENCIES.rust.tsv +55 -41
  5. data/LICENSE +201 -0
  6. data/LICENSE-MPL-2.0.txt +373 -0
  7. data/NOTICE +5 -0
  8. data/core/CHANGELOG.md +175 -0
  9. data/core/Cargo.lock +225 -298
  10. data/core/Cargo.toml +100 -94
  11. data/core/DEPENDENCIES.rust.tsv +44 -73
  12. data/core/benches/metadata/README.md +21 -0
  13. data/core/benches/metadata/main.rs +541 -0
  14. data/core/benches/vs_fs/Cargo.toml +1 -1
  15. data/core/benches/vs_s3/Cargo.toml +1 -1
  16. data/core/core/Cargo.toml +7 -2
  17. data/core/core/src/blocking/delete.rs +5 -1
  18. data/core/core/src/blocking/operator.rs +12 -0
  19. data/core/core/src/blocking/read/std_reader.rs +25 -0
  20. data/core/core/src/docs/concepts.rs +70 -94
  21. data/core/core/src/docs/internals/accessor.rs +62 -293
  22. data/core/core/src/docs/internals/layer.rs +43 -59
  23. data/core/core/src/docs/internals/mod.rs +21 -23
  24. data/core/core/src/docs/mod.rs +10 -6
  25. data/core/core/src/docs/performance/concurrent_write.md +92 -55
  26. data/core/core/src/docs/performance/http_optimization.md +120 -104
  27. data/core/core/src/docs/performance/mod.rs +8 -6
  28. data/core/core/src/docs/rfcs/5485_conditional_reader.md +4 -0
  29. data/core/core/src/docs/rfcs/7182_restore_api.md +139 -557
  30. data/core/core/src/docs/rfcs/7945_limited_read.md +210 -0
  31. data/core/core/src/docs/rfcs/7948_s3_provider_presets.md +254 -0
  32. data/core/core/src/docs/rfcs/8109_writer_copy_from.md +330 -0
  33. data/core/core/src/docs/rfcs/8145_conflict_error_kind.md +210 -0
  34. data/core/core/src/docs/rfcs/8147_write_if_not_changed.md +233 -0
  35. data/core/core/src/docs/rfcs/8188_compose_api.md +292 -0
  36. data/core/core/src/docs/rfcs/8194_compact_metadata_and_operation_args.md +444 -0
  37. data/core/core/src/docs/rfcs/README.md +14 -3
  38. data/core/core/src/docs/rfcs/mod.rs +46 -22
  39. data/core/core/src/docs/specs/README.md +34 -0
  40. data/core/core/src/docs/specs/conditional-operations.md +156 -0
  41. data/core/core/src/docs/specs/metadata.md +63 -0
  42. data/core/core/src/docs/specs/mod.rs +26 -0
  43. data/core/core/src/docs/upgrade.md +114 -1
  44. data/core/core/src/layers/capability_override.rs +15 -2
  45. data/core/core/src/layers/complete.rs +347 -43
  46. data/core/core/src/layers/correctness_check.rs +718 -51
  47. data/core/core/src/layers/error_context.rs +76 -2
  48. data/core/core/src/layers/simulate.rs +91 -28
  49. data/core/core/src/lib.rs +1 -0
  50. data/core/core/src/raw/accessor.rs +91 -15
  51. data/core/core/src/raw/enum_utils.rs +7 -0
  52. data/core/core/src/raw/http_util/header.rs +22 -17
  53. data/core/core/src/raw/oio/compose/api.rs +92 -0
  54. data/core/core/src/raw/oio/compose/mod.rs +19 -0
  55. data/core/core/src/raw/oio/copy/api.rs +3 -3
  56. data/core/core/src/raw/oio/copy/block_copy.rs +32 -4
  57. data/core/core/src/raw/oio/copy/multipart_copy.rs +36 -7
  58. data/core/core/src/raw/oio/entry.rs +48 -22
  59. data/core/core/src/raw/oio/list/flat_list.rs +1 -1
  60. data/core/core/src/raw/oio/list/hierarchy_list.rs +3 -2
  61. data/core/core/src/raw/oio/mod.rs +3 -0
  62. data/core/core/src/raw/oio/read/position_read.rs +1 -1
  63. data/core/core/src/raw/oio/write/api.rs +40 -0
  64. data/core/core/src/raw/oio/write/append_write.rs +4 -4
  65. data/core/core/src/raw/oio/write/block_write.rs +2 -2
  66. data/core/core/src/raw/oio/write/multipart_write.rs +181 -48
  67. data/core/core/src/raw/oio/write/position_write.rs +1 -1
  68. data/core/core/src/raw/operation.rs +6 -0
  69. data/core/core/src/raw/ops.rs +1191 -456
  70. data/core/core/src/raw/rps.rs +11 -0
  71. data/core/core/src/raw/time.rs +14 -3
  72. data/core/core/src/services/memory/backend.rs +5 -10
  73. data/core/core/src/services/memory/lister.rs +4 -4
  74. data/core/core/src/services/memory/writer.rs +7 -6
  75. data/core/core/src/types/buffer.rs +102 -12
  76. data/core/core/src/types/bytes_range.rs +20 -1
  77. data/core/core/src/types/capability.rs +65 -0
  78. data/core/core/src/types/compact.rs +329 -0
  79. data/core/core/src/types/compose/composer.rs +183 -0
  80. data/core/core/src/types/compose/input.rs +57 -0
  81. data/core/core/src/types/compose/mod.rs +23 -0
  82. data/core/core/src/types/context/read.rs +16 -11
  83. data/core/core/src/types/context/write.rs +150 -2
  84. data/core/core/src/types/copy.rs +5 -3
  85. data/core/core/src/types/delete/deleter.rs +20 -12
  86. data/core/core/src/types/delete/input.rs +22 -64
  87. data/core/core/src/types/delete/mod.rs +0 -1
  88. data/core/core/src/types/entry.rs +8 -14
  89. data/core/core/src/types/error.rs +28 -11
  90. data/core/core/src/types/metadata.rs +709 -322
  91. data/core/core/src/types/mod.rs +9 -1
  92. data/core/core/src/types/operator/operator.rs +278 -29
  93. data/core/core/src/types/operator/operator_futures.rs +466 -105
  94. data/core/core/src/types/options.rs +631 -158
  95. data/core/core/src/types/read/futures_async_reader.rs +663 -50
  96. data/core/core/src/types/read/reader.rs +23 -5
  97. data/core/core/src/types/write/futures_async_writer.rs +27 -0
  98. data/core/core/src/types/write/writer.rs +47 -5
  99. data/core/http-transports/reqwest/Cargo.toml +1 -1
  100. data/core/layers/async-backtrace/Cargo.toml +2 -2
  101. data/core/layers/async-backtrace/src/lib.rs +21 -2
  102. data/core/layers/await-tree/Cargo.toml +2 -2
  103. data/core/layers/await-tree/src/lib.rs +25 -2
  104. data/core/layers/capability-check/Cargo.toml +2 -2
  105. data/core/layers/capability-check/src/lib.rs +98 -10
  106. data/core/layers/chaos/Cargo.toml +2 -2
  107. data/core/layers/chaos/src/lib.rs +18 -3
  108. data/core/layers/concurrent-limit/Cargo.toml +3 -3
  109. data/core/layers/concurrent-limit/src/lib.rs +53 -13
  110. data/core/layers/dtrace/Cargo.toml +2 -2
  111. data/core/layers/dtrace/src/lib.rs +29 -2
  112. data/core/layers/fastmetrics/Cargo.toml +3 -3
  113. data/core/layers/fastrace/Cargo.toml +2 -2
  114. data/core/layers/fastrace/src/lib.rs +28 -2
  115. data/core/layers/foyer/Cargo.toml +2 -2
  116. data/core/layers/foyer/src/full.rs +16 -19
  117. data/core/layers/foyer/src/lib.rs +67 -14
  118. data/core/layers/hotpath/Cargo.toml +2 -2
  119. data/core/layers/hotpath/src/lib.rs +20 -2
  120. data/core/layers/immutable-index/Cargo.toml +2 -2
  121. data/core/layers/immutable-index/src/lib.rs +48 -24
  122. data/core/layers/logging/Cargo.toml +2 -2
  123. data/core/layers/logging/src/lib.rs +46 -2
  124. data/core/layers/metrics/Cargo.toml +3 -3
  125. data/core/layers/mime-guess/Cargo.toml +2 -2
  126. data/core/layers/mime-guess/src/lib.rs +31 -4
  127. data/core/layers/observe-metrics-common/Cargo.toml +2 -2
  128. data/core/layers/observe-metrics-common/src/lib.rs +55 -2
  129. data/core/layers/otelmetrics/Cargo.toml +3 -3
  130. data/core/layers/oteltrace/Cargo.toml +2 -2
  131. data/core/layers/oteltrace/src/lib.rs +27 -2
  132. data/core/layers/prometheus/Cargo.toml +3 -3
  133. data/core/layers/prometheus-client/Cargo.toml +3 -3
  134. data/core/layers/retry/Cargo.toml +4 -4
  135. data/core/layers/retry/src/lib.rs +76 -19
  136. data/core/layers/route/Cargo.toml +3 -3
  137. data/core/layers/route/src/lib.rs +34 -7
  138. data/core/layers/tail-cut/Cargo.toml +2 -2
  139. data/core/layers/tail-cut/src/lib.rs +28 -2
  140. data/core/layers/throttle/Cargo.toml +2 -2
  141. data/core/layers/throttle/src/lib.rs +19 -2
  142. data/core/layers/timeout/Cargo.toml +3 -3
  143. data/core/layers/timeout/src/lib.rs +38 -13
  144. data/core/layers/tracing/Cargo.toml +2 -2
  145. data/core/layers/tracing/src/lib.rs +24 -3
  146. data/core/services/aliyun-drive/Cargo.toml +2 -2
  147. data/core/services/aliyun-drive/src/backend.rs +34 -24
  148. data/core/services/aliyun-drive/src/core.rs +143 -54
  149. data/core/services/aliyun-drive/src/lister.rs +19 -18
  150. data/core/services/aliyun-drive/src/reader.rs +4 -1
  151. data/core/services/aliyun-drive/src/writer.rs +3 -3
  152. data/core/services/alluxio/Cargo.toml +1 -1
  153. data/core/services/alluxio/src/backend.rs +1 -1
  154. data/core/services/alluxio/src/core.rs +113 -94
  155. data/core/services/alluxio/src/reader.rs +7 -3
  156. data/core/services/alluxio/src/writer.rs +2 -2
  157. data/core/services/azblob/Cargo.toml +2 -2
  158. data/core/services/azblob/src/backend.rs +17 -9
  159. data/core/services/azblob/src/copier.rs +41 -15
  160. data/core/services/azblob/src/core.rs +372 -135
  161. data/core/services/azblob/src/deleter.rs +41 -18
  162. data/core/services/azblob/src/lister.rs +16 -10
  163. data/core/services/azblob/src/reader.rs +4 -1
  164. data/core/services/azblob/src/writer.rs +48 -15
  165. data/core/services/azdls/Cargo.toml +3 -3
  166. data/core/services/azdls/src/backend.rs +45 -15
  167. data/core/services/azdls/src/config.rs +4 -1
  168. data/core/services/azdls/src/core.rs +276 -87
  169. data/core/services/azdls/src/deleter.rs +13 -4
  170. data/core/services/azdls/src/lister.rs +18 -12
  171. data/core/services/azdls/src/reader.rs +6 -2
  172. data/core/services/azdls/src/writer.rs +44 -23
  173. data/core/services/azfile/Cargo.toml +2 -2
  174. data/core/services/azfile/src/backend.rs +24 -8
  175. data/core/services/azfile/src/core.rs +195 -77
  176. data/core/services/azfile/src/deleter.rs +8 -1
  177. data/core/services/azfile/src/lister.rs +20 -14
  178. data/core/services/azfile/src/reader.rs +5 -2
  179. data/core/services/azfile/src/writer.rs +27 -15
  180. data/core/services/azure-common/Cargo.toml +1 -1
  181. data/core/services/b2/Cargo.toml +2 -2
  182. data/core/services/b2/src/backend.rs +30 -11
  183. data/core/services/b2/src/core.rs +134 -120
  184. data/core/services/b2/src/deleter.rs +1 -1
  185. data/core/services/b2/src/lister.rs +5 -2
  186. data/core/services/b2/src/reader.rs +5 -2
  187. data/core/services/b2/src/writer.rs +29 -12
  188. data/core/services/cacache/Cargo.toml +1 -1
  189. data/core/services/cacache/src/backend.rs +4 -5
  190. data/core/services/cacache/src/reader.rs +4 -1
  191. data/core/services/cacache/src/writer.rs +6 -2
  192. data/core/services/cloudflare-kv/Cargo.toml +1 -1
  193. data/core/services/cloudflare-kv/src/backend.rs +26 -15
  194. data/core/services/cloudflare-kv/src/config.rs +13 -2
  195. data/core/services/cloudflare-kv/src/core.rs +62 -56
  196. data/core/services/cloudflare-kv/src/deleter.rs +12 -3
  197. data/core/services/cloudflare-kv/src/lister.rs +66 -17
  198. data/core/services/cloudflare-kv/src/reader.rs +14 -9
  199. data/core/services/cloudflare-kv/src/writer.rs +10 -7
  200. data/core/services/compfs/Cargo.toml +1 -1
  201. data/core/services/compfs/src/backend.rs +11 -7
  202. data/core/services/compfs/src/lister.rs +7 -7
  203. data/core/services/compfs/src/writer.rs +1 -1
  204. data/core/services/cos/Cargo.toml +1 -1
  205. data/core/services/cos/src/backend.rs +129 -16
  206. data/core/services/cos/src/core.rs +198 -80
  207. data/core/services/cos/src/deleter.rs +4 -1
  208. data/core/services/cos/src/lister.rs +42 -27
  209. data/core/services/cos/src/reader.rs +6 -2
  210. data/core/services/cos/src/writer.rs +45 -21
  211. data/core/services/d1/Cargo.toml +1 -1
  212. data/core/services/d1/src/backend.rs +6 -5
  213. data/core/services/d1/src/core.rs +79 -63
  214. data/core/services/d1/src/reader.rs +4 -1
  215. data/core/services/d1/src/writer.rs +6 -2
  216. data/core/services/dashmap/Cargo.toml +1 -1
  217. data/core/services/dashmap/src/backend.rs +2 -2
  218. data/core/services/dashmap/src/reader.rs +4 -1
  219. data/core/services/dashmap/src/writer.rs +11 -8
  220. data/core/services/dbfs/Cargo.toml +1 -1
  221. data/core/services/dbfs/src/backend.rs +21 -15
  222. data/core/services/dbfs/src/core.rs +65 -60
  223. data/core/services/dbfs/src/deleter.rs +4 -1
  224. data/core/services/dbfs/src/lister.rs +10 -10
  225. data/core/services/dbfs/src/writer.rs +6 -3
  226. data/core/services/dropbox/Cargo.toml +2 -2
  227. data/core/services/dropbox/src/backend.rs +30 -23
  228. data/core/services/dropbox/src/core.rs +65 -63
  229. data/core/services/dropbox/src/deleter.rs +1 -1
  230. data/core/services/dropbox/src/lister.rs +17 -8
  231. data/core/services/dropbox/src/reader.rs +4 -1
  232. data/core/services/dropbox/src/writer.rs +13 -10
  233. data/core/services/etcd/Cargo.toml +1 -1
  234. data/core/services/etcd/src/backend.rs +8 -5
  235. data/core/services/etcd/src/core.rs +5 -11
  236. data/core/services/etcd/src/lister.rs +6 -1
  237. data/core/services/etcd/src/reader.rs +4 -1
  238. data/core/services/etcd/src/writer.rs +6 -3
  239. data/core/services/foundationdb/Cargo.toml +1 -1
  240. data/core/services/foundationdb/src/backend.rs +6 -5
  241. data/core/services/foundationdb/src/reader.rs +4 -1
  242. data/core/services/foundationdb/src/writer.rs +6 -2
  243. data/core/services/foyer/Cargo.toml +3 -3
  244. data/core/services/foyer/src/backend.rs +6 -5
  245. data/core/services/foyer/src/reader.rs +4 -1
  246. data/core/services/foyer/src/writer.rs +6 -2
  247. data/core/services/fs/Cargo.toml +1 -1
  248. data/core/services/fs/src/backend.rs +4 -3
  249. data/core/services/fs/src/core.rs +44 -26
  250. data/core/services/fs/src/lister.rs +9 -6
  251. data/core/services/fs/src/writer.rs +20 -13
  252. data/core/services/ftp/Cargo.toml +4 -6
  253. data/core/services/ftp/src/backend.rs +9 -5
  254. data/core/services/ftp/src/core.rs +9 -7
  255. data/core/services/ftp/src/lister.rs +7 -8
  256. data/core/services/ftp/src/reader.rs +3 -3
  257. data/core/services/ftp/src/writer.rs +3 -3
  258. data/core/services/gcs/Cargo.toml +4 -2
  259. data/core/services/gcs/src/backend.rs +53 -7
  260. data/core/services/gcs/src/composer.rs +705 -0
  261. data/core/services/gcs/src/copier.rs +14 -4
  262. data/core/services/gcs/src/core.rs +828 -124
  263. data/core/services/gcs/src/deleter.rs +33 -18
  264. data/core/services/gcs/src/lib.rs +1 -0
  265. data/core/services/gcs/src/lister.rs +21 -12
  266. data/core/services/gcs/src/reader.rs +12 -5
  267. data/core/services/gcs/src/writer.rs +632 -10
  268. data/core/services/gcs-grpc/Cargo.toml +58 -0
  269. data/core/services/gcs-grpc/README.md +19 -0
  270. data/core/services/gcs-grpc/proto/README.md +23 -0
  271. data/core/services/gcs-grpc/proto/google/storage/v2/storage.proto +171 -0
  272. data/core/services/gcs-grpc/proto/upstream-descriptor.bin +0 -0
  273. data/core/services/gcs-grpc/src/backend.rs +449 -0
  274. data/core/services/gcs-grpc/src/config.rs +116 -0
  275. data/core/services/gcs-grpc/src/copier.rs +98 -0
  276. data/core/services/gcs-grpc/src/core.rs +298 -0
  277. data/core/services/gcs-grpc/src/deleter.rs +65 -0
  278. data/core/services/gcs-grpc/src/docs.md +19 -0
  279. data/core/services/gcs-grpc/src/generated/google.storage.v2.rs +541 -0
  280. data/core/services/gcs-grpc/src/generated/mod.rs +24 -0
  281. data/core/services/gcs-grpc/src/lib.rs +43 -0
  282. data/core/services/gcs-grpc/src/lister.rs +125 -0
  283. data/core/services/gcs-grpc/src/reader.rs +140 -0
  284. data/core/services/gcs-grpc/src/writer.rs +780 -0
  285. data/core/services/gdrive/Cargo.toml +2 -2
  286. data/core/services/gdrive/src/backend.rs +123 -69
  287. data/core/services/gdrive/src/core.rs +87 -69
  288. data/core/services/gdrive/src/deleter.rs +8 -2
  289. data/core/services/gdrive/src/lister.rs +38 -26
  290. data/core/services/gdrive/src/path_index.rs +2 -2
  291. data/core/services/gdrive/src/reader.rs +9 -3
  292. data/core/services/gdrive/src/writer.rs +13 -7
  293. data/core/services/ghac/Cargo.toml +2 -2
  294. data/core/services/ghac/src/backend.rs +5 -2
  295. data/core/services/ghac/src/core.rs +59 -37
  296. data/core/services/ghac/src/reader.rs +5 -2
  297. data/core/services/ghac/src/writer.rs +16 -6
  298. data/core/services/github/Cargo.toml +1 -1
  299. data/core/services/github/src/backend.rs +16 -8
  300. data/core/services/github/src/core.rs +88 -76
  301. data/core/services/github/src/lister.rs +17 -15
  302. data/core/services/github/src/reader.rs +5 -2
  303. data/core/services/github/src/writer.rs +12 -6
  304. data/core/services/goosefs/Cargo.toml +2 -2
  305. data/core/services/goosefs/src/backend.rs +2 -2
  306. data/core/services/goosefs/src/core.rs +291 -208
  307. data/core/services/goosefs/src/docs.md +3 -0
  308. data/core/services/goosefs/src/lister.rs +2 -3
  309. data/core/services/goosefs/src/reader.rs +7 -3
  310. data/core/services/goosefs/src/writer.rs +21 -10
  311. data/core/services/goosefs/tests/safe_conditional_put.rs +37 -0
  312. data/core/services/gridfs/Cargo.toml +2 -2
  313. data/core/services/gridfs/src/backend.rs +12 -8
  314. data/core/services/gridfs/src/core.rs +1 -1
  315. data/core/services/gridfs/src/reader.rs +4 -1
  316. data/core/services/gridfs/src/writer.rs +6 -2
  317. data/core/services/hdfs/Cargo.toml +1 -1
  318. data/core/services/hdfs/src/backend.rs +1 -1
  319. data/core/services/hdfs/src/core.rs +7 -4
  320. data/core/services/hdfs/src/lister.rs +7 -9
  321. data/core/services/hdfs/src/writer.rs +5 -1
  322. data/core/services/hdfs-native/Cargo.toml +1 -1
  323. data/core/services/hdfs-native/src/backend.rs +1 -1
  324. data/core/services/hdfs-native/src/core.rs +44 -50
  325. data/core/services/hdfs-native/src/lister.rs +8 -10
  326. data/core/services/hdfs-native/src/writer.rs +5 -1
  327. data/core/services/hf/Cargo.toml +4 -3
  328. data/core/services/hf/src/backend.rs +4 -3
  329. data/core/services/hf/src/core.rs +907 -153
  330. data/core/services/hf/src/lister.rs +16 -6
  331. data/core/services/hf/src/reader.rs +377 -57
  332. data/core/services/hf/src/writer.rs +6 -2
  333. data/core/services/http/Cargo.toml +3 -3
  334. data/core/services/http/src/backend.rs +8 -6
  335. data/core/services/http/src/core.rs +57 -35
  336. data/core/services/http/src/reader.rs +5 -2
  337. data/core/services/ipfs/Cargo.toml +1 -1
  338. data/core/services/ipfs/src/backend.rs +20 -9
  339. data/core/services/ipfs/src/core.rs +43 -34
  340. data/core/services/ipfs/src/reader.rs +5 -2
  341. data/core/services/ipmfs/Cargo.toml +1 -1
  342. data/core/services/ipmfs/src/backend.rs +17 -8
  343. data/core/services/ipmfs/src/core.rs +66 -60
  344. data/core/services/ipmfs/src/deleter.rs +5 -2
  345. data/core/services/ipmfs/src/lister.rs +15 -12
  346. data/core/services/ipmfs/src/reader.rs +5 -2
  347. data/core/services/ipmfs/src/writer.rs +6 -3
  348. data/core/services/koofr/Cargo.toml +2 -2
  349. data/core/services/koofr/src/backend.rs +46 -17
  350. data/core/services/koofr/src/core.rs +64 -48
  351. data/core/services/koofr/src/deleter.rs +4 -1
  352. data/core/services/koofr/src/lister.rs +11 -10
  353. data/core/services/koofr/src/reader.rs +5 -2
  354. data/core/services/koofr/src/writer.rs +13 -7
  355. data/core/services/lakefs/Cargo.toml +1 -1
  356. data/core/services/lakefs/src/backend.rs +25 -8
  357. data/core/services/lakefs/src/core.rs +79 -73
  358. data/core/services/lakefs/src/deleter.rs +4 -1
  359. data/core/services/lakefs/src/lister.rs +17 -14
  360. data/core/services/lakefs/src/reader.rs +5 -2
  361. data/core/services/lakefs/src/writer.rs +11 -10
  362. data/core/services/memcached/Cargo.toml +1 -1
  363. data/core/services/memcached/src/backend.rs +57 -7
  364. data/core/services/memcached/src/config.rs +13 -2
  365. data/core/services/memcached/src/core.rs +11 -1
  366. data/core/services/memcached/src/reader.rs +4 -1
  367. data/core/services/memcached/src/writer.rs +6 -2
  368. data/core/services/mini_moka/Cargo.toml +1 -1
  369. data/core/services/mini_moka/src/backend.rs +8 -8
  370. data/core/services/mini_moka/src/reader.rs +4 -1
  371. data/core/services/mini_moka/src/writer.rs +11 -7
  372. data/core/services/moka/Cargo.toml +1 -1
  373. data/core/services/moka/src/backend.rs +7 -7
  374. data/core/services/moka/src/reader.rs +4 -1
  375. data/core/services/moka/src/writer.rs +10 -6
  376. data/core/services/mongodb/Cargo.toml +2 -2
  377. data/core/services/mongodb/src/backend.rs +7 -6
  378. data/core/services/mongodb/src/core.rs +1 -1
  379. data/core/services/mongodb/src/reader.rs +4 -1
  380. data/core/services/mongodb/src/writer.rs +6 -2
  381. data/core/services/monoiofs/Cargo.toml +2 -2
  382. data/core/services/monoiofs/src/backend.rs +16 -10
  383. data/core/services/monoiofs/src/core.rs +8 -9
  384. data/core/services/monoiofs/src/reader.rs +8 -10
  385. data/core/services/monoiofs/src/writer.rs +19 -24
  386. data/core/services/mysql/Cargo.toml +2 -2
  387. data/core/services/mysql/src/backend.rs +7 -6
  388. data/core/services/mysql/src/core.rs +1 -1
  389. data/core/services/mysql/src/lister.rs +7 -3
  390. data/core/services/mysql/src/reader.rs +4 -1
  391. data/core/services/mysql/src/writer.rs +6 -2
  392. data/core/services/obs/Cargo.toml +1 -1
  393. data/core/services/obs/src/backend.rs +29 -11
  394. data/core/services/obs/src/core.rs +81 -82
  395. data/core/services/obs/src/deleter.rs +4 -1
  396. data/core/services/obs/src/lister.rs +12 -5
  397. data/core/services/obs/src/reader.rs +5 -2
  398. data/core/services/obs/src/writer.rs +40 -19
  399. data/core/services/onedrive/Cargo.toml +2 -2
  400. data/core/services/onedrive/src/backend.rs +30 -21
  401. data/core/services/onedrive/src/config.rs +2 -2
  402. data/core/services/onedrive/src/core.rs +191 -90
  403. data/core/services/onedrive/src/deleter.rs +5 -2
  404. data/core/services/onedrive/src/graph_model.rs +10 -51
  405. data/core/services/onedrive/src/lister.rs +60 -24
  406. data/core/services/onedrive/src/reader.rs +17 -2
  407. data/core/services/onedrive/src/writer.rs +26 -15
  408. data/core/services/opfs/Cargo.toml +1 -1
  409. data/core/services/opfs/src/backend.rs +6 -13
  410. data/core/services/opfs/src/core.rs +33 -37
  411. data/core/services/opfs/src/lister.rs +4 -4
  412. data/core/services/opfs/src/writer.rs +1 -3
  413. data/core/services/oss/Cargo.toml +1 -1
  414. data/core/services/oss/src/backend.rs +40 -8
  415. data/core/services/oss/src/core.rs +192 -92
  416. data/core/services/oss/src/deleter.rs +16 -6
  417. data/core/services/oss/src/lister.rs +43 -27
  418. data/core/services/oss/src/reader.rs +6 -2
  419. data/core/services/oss/src/writer.rs +40 -22
  420. data/core/services/pcloud/Cargo.toml +1 -1
  421. data/core/services/pcloud/src/backend.rs +40 -6
  422. data/core/services/pcloud/src/core.rs +80 -66
  423. data/core/services/pcloud/src/deleter.rs +8 -1
  424. data/core/services/pcloud/src/lister.rs +4 -1
  425. data/core/services/pcloud/src/reader.rs +5 -2
  426. data/core/services/pcloud/src/writer.rs +6 -3
  427. data/core/services/persy/Cargo.toml +1 -1
  428. data/core/services/persy/src/backend.rs +6 -5
  429. data/core/services/persy/src/core.rs +60 -15
  430. data/core/services/persy/src/reader.rs +4 -1
  431. data/core/services/persy/src/writer.rs +6 -2
  432. data/core/services/postgresql/Cargo.toml +2 -2
  433. data/core/services/postgresql/src/backend.rs +7 -6
  434. data/core/services/postgresql/src/core.rs +1 -1
  435. data/core/services/postgresql/src/reader.rs +4 -1
  436. data/core/services/postgresql/src/writer.rs +6 -2
  437. data/core/services/redb/Cargo.toml +1 -1
  438. data/core/services/redb/src/backend.rs +6 -5
  439. data/core/services/redb/src/reader.rs +4 -1
  440. data/core/services/redb/src/writer.rs +6 -2
  441. data/core/services/redis/Cargo.toml +1 -1
  442. data/core/services/redis/src/backend.rs +18 -8
  443. data/core/services/redis/src/config.rs +13 -2
  444. data/core/services/redis/src/reader.rs +8 -4
  445. data/core/services/redis/src/writer.rs +6 -2
  446. data/core/services/rocksdb/Cargo.toml +1 -1
  447. data/core/services/rocksdb/src/backend.rs +6 -5
  448. data/core/services/rocksdb/src/lister.rs +6 -5
  449. data/core/services/rocksdb/src/reader.rs +4 -1
  450. data/core/services/rocksdb/src/writer.rs +6 -2
  451. data/core/services/s3/Cargo.toml +5 -4
  452. data/core/services/s3/src/backend.rs +995 -39
  453. data/core/services/s3/src/compatible_services.md +57 -0
  454. data/core/services/s3/src/config.rs +16 -0
  455. data/core/services/s3/src/copier.rs +190 -55
  456. data/core/services/s3/src/core.rs +299 -190
  457. data/core/services/s3/src/deleter.rs +26 -7
  458. data/core/services/s3/src/docs.md +57 -0
  459. data/core/services/s3/src/lister.rs +55 -36
  460. data/core/services/s3/src/reader.rs +22 -2
  461. data/core/services/s3/src/writer.rs +154 -32
  462. data/core/services/seafile/Cargo.toml +2 -2
  463. data/core/services/seafile/src/backend.rs +3 -3
  464. data/core/services/seafile/src/core.rs +105 -79
  465. data/core/services/seafile/src/lister.rs +11 -8
  466. data/core/services/seafile/src/reader.rs +5 -2
  467. data/core/services/seafile/src/writer.rs +6 -3
  468. data/core/services/sftp/Cargo.toml +1 -1
  469. data/core/services/sftp/src/backend.rs +19 -4
  470. data/core/services/sftp/src/core.rs +51 -46
  471. data/core/services/sftp/src/lister.rs +4 -4
  472. data/core/services/sftp/src/writer.rs +1 -1
  473. data/core/services/sled/Cargo.toml +1 -1
  474. data/core/services/sled/src/backend.rs +6 -5
  475. data/core/services/sled/src/core.rs +28 -6
  476. data/core/services/sled/src/lister.rs +6 -5
  477. data/core/services/sled/src/reader.rs +4 -1
  478. data/core/services/sled/src/writer.rs +6 -2
  479. data/core/services/sqlite/Cargo.toml +2 -2
  480. data/core/services/sqlite/src/backend.rs +12 -7
  481. data/core/services/sqlite/src/core.rs +3 -3
  482. data/core/services/sqlite/src/reader.rs +4 -1
  483. data/core/services/sqlite/src/writer.rs +7 -3
  484. data/core/services/surrealdb/Cargo.toml +2 -2
  485. data/core/services/surrealdb/src/backend.rs +7 -6
  486. data/core/services/surrealdb/src/core.rs +1 -1
  487. data/core/services/surrealdb/src/reader.rs +4 -1
  488. data/core/services/surrealdb/src/writer.rs +6 -2
  489. data/core/services/swift/Cargo.toml +1 -1
  490. data/core/services/swift/src/backend.rs +38 -8
  491. data/core/services/swift/src/core.rs +63 -67
  492. data/core/services/swift/src/deleter.rs +8 -2
  493. data/core/services/swift/src/lister.rs +11 -8
  494. data/core/services/swift/src/reader.rs +5 -2
  495. data/core/services/swift/src/writer.rs +17 -8
  496. data/core/services/tikv/Cargo.toml +2 -2
  497. data/core/services/tikv/src/backend.rs +7 -6
  498. data/core/services/tikv/src/core.rs +31 -14
  499. data/core/services/tikv/src/reader.rs +4 -1
  500. data/core/services/tikv/src/writer.rs +6 -2
  501. data/core/services/tos/Cargo.toml +2 -2
  502. data/core/services/tos/src/backend.rs +45 -21
  503. data/core/services/tos/src/copier.rs +44 -17
  504. data/core/services/tos/src/core.rs +147 -117
  505. data/core/services/tos/src/deleter.rs +9 -3
  506. data/core/services/tos/src/docs.md +1 -1
  507. data/core/services/tos/src/lister.rs +43 -28
  508. data/core/services/tos/src/reader.rs +5 -2
  509. data/core/services/tos/src/writer.rs +37 -16
  510. data/core/services/upyun/Cargo.toml +1 -1
  511. data/core/services/upyun/src/backend.rs +30 -7
  512. data/core/services/upyun/src/core.rs +122 -87
  513. data/core/services/upyun/src/deleter.rs +4 -1
  514. data/core/services/upyun/src/lister.rs +10 -10
  515. data/core/services/upyun/src/reader.rs +5 -2
  516. data/core/services/upyun/src/writer.rs +19 -7
  517. data/core/services/vercel-artifacts/Cargo.toml +1 -1
  518. data/core/services/vercel-artifacts/src/backend.rs +6 -3
  519. data/core/services/vercel-artifacts/src/core.rs +32 -27
  520. data/core/services/vercel-artifacts/src/reader.rs +5 -2
  521. data/core/services/vercel-artifacts/src/writer.rs +6 -3
  522. data/core/services/vercel-blob/Cargo.toml +1 -1
  523. data/core/services/vercel-blob/src/backend.rs +23 -6
  524. data/core/services/vercel-blob/src/core.rs +92 -81
  525. data/core/services/vercel-blob/src/lister.rs +12 -3
  526. data/core/services/vercel-blob/src/reader.rs +5 -2
  527. data/core/services/vercel-blob/src/writer.rs +19 -7
  528. data/core/services/webdav/Cargo.toml +2 -2
  529. data/core/services/webdav/src/backend.rs +25 -5
  530. data/core/services/webdav/src/core.rs +116 -59
  531. data/core/services/webdav/src/deleter.rs +4 -1
  532. data/core/services/webdav/src/lister.rs +4 -1
  533. data/core/services/webdav/src/reader.rs +6 -2
  534. data/core/services/webdav/src/writer.rs +17 -7
  535. data/core/services/webhdfs/Cargo.toml +2 -2
  536. data/core/services/webhdfs/src/backend.rs +24 -11
  537. data/core/services/webhdfs/src/core.rs +99 -98
  538. data/core/services/webhdfs/src/deleter.rs +5 -2
  539. data/core/services/webhdfs/src/lister.rs +21 -9
  540. data/core/services/webhdfs/src/reader.rs +5 -2
  541. data/core/services/webhdfs/src/writer.rs +49 -14
  542. data/core/services/yandex-disk/Cargo.toml +1 -1
  543. data/core/services/yandex-disk/src/backend.rs +28 -6
  544. data/core/services/yandex-disk/src/core.rs +97 -79
  545. data/core/services/yandex-disk/src/deleter.rs +4 -1
  546. data/core/services/yandex-disk/src/lister.rs +25 -9
  547. data/core/services/yandex-disk/src/reader.rs +5 -2
  548. data/core/services/yandex-disk/src/writer.rs +6 -3
  549. data/core/src/lib.rs +5 -0
  550. data/core/testkit/Cargo.toml +4 -4
  551. data/core/testkit/src/utils.rs +53 -8
  552. data/core/tests/behavior/async_compose.rs +297 -0
  553. data/core/tests/behavior/async_copy.rs +162 -1
  554. data/core/tests/behavior/async_delete.rs +364 -3
  555. data/core/tests/behavior/async_read.rs +86 -0
  556. data/core/tests/behavior/async_restore.rs +162 -0
  557. data/core/tests/behavior/async_stat.rs +90 -0
  558. data/core/tests/behavior/async_write.rs +330 -2
  559. data/core/tests/behavior/main.rs +4 -0
  560. data/core/upgrade.md +114 -1
  561. data/src/capability.rs +0 -1
  562. data/src/io.rs +0 -1
  563. data/src/lister.rs +0 -1
  564. data/src/metadata.rs +0 -1
  565. data/src/operator_info.rs +0 -1
  566. metadata +44 -2
@@ -0,0 +1,541 @@
1
+ // Licensed to the Apache Software Foundation (ASF) under one
2
+ // or more contributor license agreements. See the NOTICE file
3
+ // distributed with this work for additional information
4
+ // regarding copyright ownership. The ASF licenses this file
5
+ // to you under the Apache License, Version 2.0 (the
6
+ // "License"); you may not use this file except in compliance
7
+ // with the License. You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing,
12
+ // software distributed under the License is distributed on an
13
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ // KIND, either express or implied. See the License for the
15
+ // specific language governing permissions and limitations
16
+ // under the License.
17
+
18
+ use std::collections::HashMap;
19
+ use std::mem;
20
+
21
+ use divan::AllocProfiler;
22
+ use divan::Bencher;
23
+ use divan::black_box;
24
+ use divan::black_box_drop;
25
+ use opendal::Capability;
26
+ use opendal::EntryMode;
27
+ use opendal::Metadata;
28
+ use opendal::MetadataBuilder;
29
+ use opendal::options::ReadOptions;
30
+ use opendal::options::WriteOptions;
31
+ use opendal::raw::OpRead;
32
+ use opendal::raw::OpWrite;
33
+ use opendal::raw::Timestamp;
34
+ use opendal::raw::oio::Entry;
35
+
36
+ #[global_allocator]
37
+ static ALLOC: AllocProfiler = AllocProfiler::system();
38
+
39
+ const CACHE_CONTROL: &str = "public, max-age=3600";
40
+ const CONTENT_DISPOSITION: &str = "attachment; filename=benchmark-object.json";
41
+ const CONTENT_MD5: &str = "1B2M2Y8AsgTpgAmY7PhCfg==";
42
+ const CONTENT_TYPE: &str = "application/json";
43
+ const CONTENT_ENCODING: &str = "gzip";
44
+ const ETAG: &str = "\"33a64df551425fcc55e4d42a148795d9f25f89d4\"";
45
+ const UPDATED_ETAG: &str = "\"b1946ac92492d2347c6235b4d2611184\"";
46
+ const VERSION: &str = "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHYiHf91CDq0";
47
+ const PATH: &str = "benchmarks/metadata/representative-object.json";
48
+
49
+ fn main() {
50
+ println!(
51
+ "layout: metadata legacy={} compact={} entry legacy={} compact={}",
52
+ mem::size_of::<LegacyMetadata>(),
53
+ mem::size_of::<Metadata>(),
54
+ mem::size_of::<LegacyEntry>(),
55
+ mem::size_of::<Entry>(),
56
+ );
57
+ println!(
58
+ "raw layout: read legacy={} compact={} write legacy={} compact={}",
59
+ mem::size_of::<LegacyOpRead>(),
60
+ mem::size_of::<OpRead>(),
61
+ mem::size_of::<LegacyOpWrite>(),
62
+ mem::size_of::<OpWrite>(),
63
+ );
64
+ divan::main();
65
+ }
66
+
67
+ #[derive(Clone, Copy, Debug)]
68
+ enum Profile {
69
+ List,
70
+ Stat,
71
+ UserMetadata,
72
+ }
73
+
74
+ const PROFILES: &[Profile] = &[Profile::List, Profile::Stat, Profile::UserMetadata];
75
+
76
+ #[allow(dead_code)]
77
+ #[derive(Clone, Default)]
78
+ struct LegacyMetadata {
79
+ mode: EntryMode,
80
+ is_current: Option<bool>,
81
+ is_deleted: bool,
82
+ cache_control: Option<String>,
83
+ content_disposition: Option<String>,
84
+ content_length: Option<u64>,
85
+ content_md5: Option<String>,
86
+ content_type: Option<String>,
87
+ content_encoding: Option<String>,
88
+ etag: Option<String>,
89
+ last_modified: Option<Timestamp>,
90
+ version: Option<String>,
91
+ user_metadata: Option<HashMap<String, String>>,
92
+ }
93
+
94
+ #[allow(dead_code)]
95
+ struct LegacyEntry {
96
+ path: String,
97
+ metadata: LegacyMetadata,
98
+ }
99
+
100
+ #[allow(dead_code)]
101
+ #[derive(Clone, Default)]
102
+ struct LegacyOpRead {
103
+ if_match: Option<String>,
104
+ if_none_match: Option<String>,
105
+ if_version_match: Option<String>,
106
+ if_version_not_match: Option<String>,
107
+ if_modified_since: Option<Timestamp>,
108
+ if_unmodified_since: Option<Timestamp>,
109
+ override_content_type: Option<String>,
110
+ override_cache_control: Option<String>,
111
+ override_content_disposition: Option<String>,
112
+ version: Option<String>,
113
+ content_length_hint: Option<u64>,
114
+ }
115
+
116
+ impl From<ReadOptions> for LegacyOpRead {
117
+ fn from(value: ReadOptions) -> Self {
118
+ Self {
119
+ if_match: value.if_match,
120
+ if_none_match: value.if_none_match,
121
+ if_version_match: value.if_version_match,
122
+ if_version_not_match: value.if_version_not_match,
123
+ if_modified_since: value.if_modified_since,
124
+ if_unmodified_since: value.if_unmodified_since,
125
+ override_content_type: value.override_content_type,
126
+ override_cache_control: value.override_cache_control,
127
+ override_content_disposition: value.override_content_disposition,
128
+ version: value.version,
129
+ content_length_hint: value.content_length_hint,
130
+ }
131
+ }
132
+ }
133
+
134
+ #[allow(dead_code)]
135
+ #[derive(Clone, Default)]
136
+ struct LegacyOpWrite {
137
+ append: bool,
138
+ concurrent: usize,
139
+ content_type: Option<String>,
140
+ content_disposition: Option<String>,
141
+ content_encoding: Option<String>,
142
+ cache_control: Option<String>,
143
+ if_match: Option<String>,
144
+ if_none_match: Option<String>,
145
+ if_version_match: Option<String>,
146
+ if_version_not_match: Option<String>,
147
+ if_not_exists: bool,
148
+ user_metadata: Option<HashMap<String, String>>,
149
+ }
150
+
151
+ impl From<WriteOptions> for LegacyOpWrite {
152
+ fn from(value: WriteOptions) -> Self {
153
+ Self {
154
+ append: value.append,
155
+ concurrent: value.concurrent,
156
+ content_type: value.content_type,
157
+ content_disposition: value.content_disposition,
158
+ content_encoding: value.content_encoding,
159
+ cache_control: value.cache_control,
160
+ if_match: value.if_match,
161
+ if_none_match: value.if_none_match,
162
+ if_version_match: value.if_version_match,
163
+ if_version_not_match: value.if_version_not_match,
164
+ if_not_exists: value.if_not_exists,
165
+ user_metadata: value.user_metadata,
166
+ }
167
+ }
168
+ }
169
+
170
+ fn timestamp() -> Timestamp {
171
+ Timestamp::new(1_700_000_000, 123_456_789).expect("timestamp is valid")
172
+ }
173
+
174
+ fn make_user_metadata() -> HashMap<String, String> {
175
+ HashMap::from([
176
+ (
177
+ "request-id".to_string(),
178
+ "01HZX3K8R4N8YV6YQ5B6F3S2T1".to_string(),
179
+ ),
180
+ ("tenant".to_string(), "benchmark-tenant".to_string()),
181
+ (
182
+ "trace-id".to_string(),
183
+ "4bf92f3577b34da6a3ce929d0e0e4736".to_string(),
184
+ ),
185
+ ("region".to_string(), "us-west-2".to_string()),
186
+ ("pipeline".to_string(), "metadata-retention".to_string()),
187
+ ("source".to_string(), "benchmark".to_string()),
188
+ ("schema".to_string(), "v3".to_string()),
189
+ ("owner".to_string(), "opendal".to_string()),
190
+ ])
191
+ }
192
+
193
+ fn make_legacy(profile: Profile) -> LegacyMetadata {
194
+ let mut metadata = LegacyMetadata {
195
+ mode: EntryMode::FILE,
196
+ content_length: Some(4 * 1024 * 1024),
197
+ etag: Some(ETAG.to_string()),
198
+ last_modified: Some(timestamp()),
199
+ ..Default::default()
200
+ };
201
+
202
+ if matches!(profile, Profile::Stat | Profile::UserMetadata) {
203
+ metadata.cache_control = Some(CACHE_CONTROL.to_string());
204
+ metadata.content_disposition = Some(CONTENT_DISPOSITION.to_string());
205
+ metadata.content_md5 = Some(CONTENT_MD5.to_string());
206
+ metadata.content_type = Some(CONTENT_TYPE.to_string());
207
+ metadata.content_encoding = Some(CONTENT_ENCODING.to_string());
208
+ metadata.version = Some(VERSION.to_string());
209
+ }
210
+ if matches!(profile, Profile::UserMetadata) {
211
+ metadata.user_metadata = Some(make_user_metadata());
212
+ }
213
+ metadata
214
+ }
215
+
216
+ fn make_compact(profile: Profile) -> Metadata {
217
+ let mut metadata = MetadataBuilder::file(4 * 1024 * 1024);
218
+ metadata.etag(ETAG).last_modified(timestamp());
219
+
220
+ if matches!(profile, Profile::Stat | Profile::UserMetadata) {
221
+ metadata
222
+ .cache_control(CACHE_CONTROL)
223
+ .content_disposition(CONTENT_DISPOSITION)
224
+ .content_md5(CONTENT_MD5)
225
+ .content_type(CONTENT_TYPE)
226
+ .content_encoding(CONTENT_ENCODING)
227
+ .version(VERSION);
228
+ }
229
+ if matches!(profile, Profile::UserMetadata) {
230
+ metadata.user_metadata(make_user_metadata());
231
+ }
232
+ metadata.build()
233
+ }
234
+
235
+ fn make_read_options() -> ReadOptions {
236
+ ReadOptions {
237
+ version: Some(VERSION.to_string()),
238
+ if_match: Some(ETAG.to_string()),
239
+ if_none_match: Some(UPDATED_ETAG.to_string()),
240
+ if_version_match: Some("generation-42".to_string()),
241
+ if_version_not_match: Some("generation-41".to_string()),
242
+ if_modified_since: Some(timestamp()),
243
+ if_unmodified_since: Some(timestamp()),
244
+ content_length_hint: Some(4 * 1024 * 1024),
245
+ override_content_type: Some(CONTENT_TYPE.to_string()),
246
+ override_cache_control: Some(CACHE_CONTROL.to_string()),
247
+ override_content_disposition: Some(CONTENT_DISPOSITION.to_string()),
248
+ ..Default::default()
249
+ }
250
+ }
251
+
252
+ fn make_write_options() -> WriteOptions {
253
+ WriteOptions {
254
+ append: true,
255
+ concurrent: 8,
256
+ content_type: Some(CONTENT_TYPE.to_string()),
257
+ content_disposition: Some(CONTENT_DISPOSITION.to_string()),
258
+ content_encoding: Some(CONTENT_ENCODING.to_string()),
259
+ cache_control: Some(CACHE_CONTROL.to_string()),
260
+ if_match: Some(ETAG.to_string()),
261
+ if_none_match: Some(UPDATED_ETAG.to_string()),
262
+ if_version_match: Some("generation-42".to_string()),
263
+ if_version_not_match: Some("generation-41".to_string()),
264
+ if_not_exists: true,
265
+ user_metadata: Some(make_user_metadata()),
266
+ ..Default::default()
267
+ }
268
+ }
269
+
270
+ fn make_op_read() -> OpRead {
271
+ let (_, args, _) = make_read_options().into();
272
+ args
273
+ }
274
+
275
+ fn make_op_write() -> OpWrite {
276
+ OpWrite::from_options(&Capability::default(), make_write_options())
277
+ .expect("options do not contain a logical condition")
278
+ .0
279
+ }
280
+
281
+ mod construction {
282
+ use super::*;
283
+
284
+ #[divan::bench(args = PROFILES)]
285
+ fn legacy(bencher: Bencher, profile: Profile) {
286
+ bencher.bench(|| black_box(make_legacy(profile)));
287
+ }
288
+
289
+ #[divan::bench(args = PROFILES)]
290
+ fn compact(bencher: Bencher, profile: Profile) {
291
+ bencher.bench(|| black_box(make_compact(profile)));
292
+ }
293
+ }
294
+
295
+ mod retain_10k {
296
+ use super::*;
297
+
298
+ const ENTRIES: usize = 10_000;
299
+
300
+ #[divan::bench(args = PROFILES)]
301
+ fn legacy(bencher: Bencher, profile: Profile) {
302
+ bencher.bench(|| {
303
+ black_box(
304
+ (0..ENTRIES)
305
+ .map(|_| make_legacy(profile))
306
+ .collect::<Vec<_>>(),
307
+ )
308
+ });
309
+ }
310
+
311
+ #[divan::bench(args = PROFILES)]
312
+ fn compact(bencher: Bencher, profile: Profile) {
313
+ bencher.bench(|| {
314
+ black_box(
315
+ (0..ENTRIES)
316
+ .map(|_| make_compact(profile))
317
+ .collect::<Vec<_>>(),
318
+ )
319
+ });
320
+ }
321
+ }
322
+
323
+ mod retain_10k_entries {
324
+ use super::*;
325
+
326
+ const ENTRIES: usize = 10_000;
327
+
328
+ #[divan::bench]
329
+ fn legacy(bencher: Bencher) {
330
+ bencher.bench(|| {
331
+ black_box(
332
+ (0..ENTRIES)
333
+ .map(|_| LegacyEntry {
334
+ path: PATH.to_string(),
335
+ metadata: make_legacy(Profile::List),
336
+ })
337
+ .collect::<Vec<_>>(),
338
+ )
339
+ });
340
+ }
341
+
342
+ #[divan::bench]
343
+ fn compact(bencher: Bencher) {
344
+ bencher.bench(|| {
345
+ black_box(
346
+ (0..ENTRIES)
347
+ .map(|_| Entry::new(PATH, make_compact(Profile::List)))
348
+ .collect::<Vec<_>>(),
349
+ )
350
+ });
351
+ }
352
+ }
353
+
354
+ mod lookup {
355
+ use super::*;
356
+
357
+ #[divan::bench]
358
+ fn legacy_string(bencher: Bencher) {
359
+ bencher
360
+ .with_inputs(|| make_legacy(Profile::Stat))
361
+ .bench_refs(|metadata| black_box(metadata.etag.as_deref().map(str::len)));
362
+ }
363
+
364
+ #[divan::bench]
365
+ fn compact_string(bencher: Bencher) {
366
+ bencher
367
+ .with_inputs(|| make_compact(Profile::Stat))
368
+ .bench_refs(|metadata| black_box(metadata.etag().map(str::len)));
369
+ }
370
+
371
+ #[divan::bench]
372
+ fn legacy_user_metadata(bencher: Bencher) {
373
+ bencher
374
+ .with_inputs(|| make_legacy(Profile::UserMetadata))
375
+ .bench_refs(|metadata| {
376
+ black_box(
377
+ metadata
378
+ .user_metadata
379
+ .as_ref()
380
+ .and_then(|values| values.get("request-id"))
381
+ .map(String::len),
382
+ )
383
+ });
384
+ }
385
+
386
+ #[divan::bench]
387
+ fn compact_user_metadata(bencher: Bencher) {
388
+ bencher
389
+ .with_inputs(|| make_compact(Profile::UserMetadata))
390
+ .bench_refs(|metadata| {
391
+ black_box(
392
+ metadata
393
+ .user_metadata()
394
+ .and_then(|values| values.get("request-id"))
395
+ .map(str::len),
396
+ )
397
+ });
398
+ }
399
+ }
400
+
401
+ mod clone {
402
+ use super::*;
403
+
404
+ #[divan::bench(args = PROFILES)]
405
+ fn legacy(bencher: Bencher, profile: Profile) {
406
+ bencher
407
+ .with_inputs(|| make_legacy(profile))
408
+ .bench_refs(|metadata| black_box_drop(metadata.clone()));
409
+ }
410
+
411
+ #[divan::bench(args = PROFILES)]
412
+ fn compact(bencher: Bencher, profile: Profile) {
413
+ bencher
414
+ .with_inputs(|| make_compact(profile))
415
+ .bench_refs(|metadata| black_box_drop(metadata.clone()));
416
+ }
417
+ }
418
+
419
+ mod clone_then_modify {
420
+ use super::*;
421
+
422
+ #[divan::bench(args = PROFILES)]
423
+ fn legacy(bencher: Bencher, profile: Profile) {
424
+ bencher
425
+ .with_inputs(|| make_legacy(profile))
426
+ .bench_refs(|metadata| {
427
+ let mut metadata = metadata.clone();
428
+ metadata.etag = Some(UPDATED_ETAG.to_string());
429
+ black_box_drop(metadata);
430
+ });
431
+ }
432
+
433
+ #[divan::bench(args = PROFILES)]
434
+ fn compact(bencher: Bencher, profile: Profile) {
435
+ bencher
436
+ .with_inputs(|| make_compact(profile))
437
+ .bench_refs(|metadata| {
438
+ let mut builder = metadata.clone().into_builder();
439
+ builder.etag(UPDATED_ETAG);
440
+ black_box_drop(builder.build());
441
+ });
442
+ }
443
+ }
444
+
445
+ mod raw_freeze {
446
+ use super::*;
447
+
448
+ #[divan::bench]
449
+ fn legacy_read(bencher: Bencher) {
450
+ bencher
451
+ .with_inputs(make_read_options)
452
+ .bench_values(|options| black_box(LegacyOpRead::from(options)));
453
+ }
454
+
455
+ #[divan::bench]
456
+ fn compact_read(bencher: Bencher) {
457
+ bencher
458
+ .with_inputs(make_read_options)
459
+ .bench_values(|options| {
460
+ let (_, args, _): (_, OpRead, _) = options.into();
461
+ black_box(args)
462
+ });
463
+ }
464
+
465
+ #[divan::bench]
466
+ fn legacy_write(bencher: Bencher) {
467
+ bencher
468
+ .with_inputs(make_write_options)
469
+ .bench_values(|options| black_box(LegacyOpWrite::from(options)));
470
+ }
471
+
472
+ #[divan::bench]
473
+ fn compact_write(bencher: Bencher) {
474
+ bencher
475
+ .with_inputs(make_write_options)
476
+ .bench_values(|options| {
477
+ black_box(
478
+ OpWrite::from_options(&Capability::default(), options)
479
+ .expect("options do not contain a logical condition")
480
+ .0,
481
+ )
482
+ });
483
+ }
484
+ }
485
+
486
+ mod raw_clone {
487
+ use super::*;
488
+
489
+ #[divan::bench]
490
+ fn legacy_read(bencher: Bencher) {
491
+ bencher
492
+ .with_inputs(|| LegacyOpRead::from(make_read_options()))
493
+ .bench_refs(|args| black_box_drop(args.clone()));
494
+ }
495
+
496
+ #[divan::bench]
497
+ fn compact_read(bencher: Bencher) {
498
+ bencher
499
+ .with_inputs(make_op_read)
500
+ .bench_refs(|args| black_box_drop(args.clone()));
501
+ }
502
+
503
+ #[divan::bench]
504
+ fn legacy_write(bencher: Bencher) {
505
+ bencher
506
+ .with_inputs(|| LegacyOpWrite::from(make_write_options()))
507
+ .bench_refs(|args| black_box_drop(args.clone()));
508
+ }
509
+
510
+ #[divan::bench]
511
+ fn compact_write(bencher: Bencher) {
512
+ bencher
513
+ .with_inputs(make_op_write)
514
+ .bench_refs(|args| black_box_drop(args.clone()));
515
+ }
516
+ }
517
+
518
+ mod scalar_placement {
519
+ use super::*;
520
+
521
+ #[divan::bench]
522
+ fn legacy(bencher: Bencher) {
523
+ bencher.bench(|| {
524
+ black_box(LegacyMetadata {
525
+ mode: EntryMode::FILE,
526
+ content_length: Some(4 * 1024 * 1024),
527
+ last_modified: Some(timestamp()),
528
+ ..Default::default()
529
+ })
530
+ });
531
+ }
532
+
533
+ #[divan::bench]
534
+ fn compact(bencher: Bencher) {
535
+ bencher.bench(|| {
536
+ let mut metadata = MetadataBuilder::file(4 * 1024 * 1024);
537
+ metadata.last_modified(timestamp());
538
+ black_box(metadata.build())
539
+ });
540
+ }
541
+ }
@@ -22,7 +22,7 @@ license = "Apache-2.0"
22
22
  name = "opendal-benchmark-vs-fs"
23
23
  publish = false
24
24
  rust-version = "1.86"
25
- version = "0.58.1"
25
+ version = "0.59.0"
26
26
 
27
27
  [dependencies]
28
28
  criterion = { version = "0.8.2", features = ["async", "async_tokio"] }
@@ -22,7 +22,7 @@ license = "Apache-2.0"
22
22
  name = "opendal-benchmark-vs-s3"
23
23
  publish = false
24
24
  rust-version = "1.86"
25
- version = "0.58.1"
25
+ version = "0.59.0"
26
26
 
27
27
  [dependencies]
28
28
  aws-config = { version = "1.0.1", features = ["behavior-version-latest"] }
data/core/core/Cargo.toml CHANGED
@@ -66,6 +66,7 @@ bench = false
66
66
  [dependencies]
67
67
  # Required dependencies
68
68
  anyhow = { version = "1.0.100", features = ["std"] }
69
+ asyncband = { workspace = true }
69
70
  base64 = { workspace = true }
70
71
  bytes = { workspace = true }
71
72
  futures = { workspace = true, features = ["std", "async-await"] }
@@ -73,7 +74,6 @@ http = { workspace = true }
73
74
  jiff = { version = "0.2.28", features = ["serde"] }
74
75
  log = { workspace = true }
75
76
  md-5 = "0.11.0"
76
- mea = { workspace = true }
77
77
  percent-encoding = "2"
78
78
  quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
79
79
  reqsign-core = { version = "3.2.0", default-features = false, optional = true }
@@ -96,4 +96,9 @@ logforth = { workspace = true }
96
96
  pretty_assertions = "1"
97
97
  rand = { workspace = true }
98
98
  sha2 = { workspace = true }
99
- tokio = { workspace = true, features = ["fs", "macros", "rt-multi-thread"] }
99
+ tokio = { workspace = true, features = [
100
+ "fs",
101
+ "macros",
102
+ "rt-multi-thread",
103
+ "time",
104
+ ] }
@@ -31,7 +31,11 @@ impl Deleter {
31
31
  Ok(Self { handle, inner })
32
32
  }
33
33
 
34
- /// Delete a path.
34
+ /// Delete a path with default or per-entry options.
35
+ ///
36
+ /// Pass a path directly to use [`options::DeleteOptions::default`]. Pass
37
+ /// `(String, DeleteOptions)` when this entry needs version or condition
38
+ /// options.
35
39
  pub fn delete(&mut self, input: impl IntoDeleteInput) -> Result<()> {
36
40
  self.handle.block_on(self.inner.delete(input))
37
41
  }
@@ -654,6 +654,18 @@ impl Operator {
654
654
  self.spawn_block(async move { op.rename_options(&from, &to, opts).await })?
655
655
  }
656
656
 
657
+ /// Restore the given path from its latest deleted state.
658
+ pub fn restore(&self, path: &str) -> Result<()> {
659
+ self.restore_options(path, options::RestoreOptions::default())
660
+ }
661
+
662
+ /// Restore the given path with additional options.
663
+ pub fn restore_options(&self, path: &str, opts: options::RestoreOptions) -> Result<()> {
664
+ let op = self.op.clone();
665
+ let path = path.to_string();
666
+ self.spawn_block(async move { op.restore_options(&path, opts).await })?
667
+ }
668
+
657
669
  /// Delete given path.
658
670
  ///
659
671
  /// # Notes
@@ -44,6 +44,31 @@ impl StdReader {
44
44
  pub(super) fn new(handle: tokio::runtime::Handle, r: FuturesAsyncReader) -> Self {
45
45
  Self { handle, r: Some(r) }
46
46
  }
47
+
48
+ /// Read at most `size` bytes and return them as an OpenDAL [`Buffer`].
49
+ ///
50
+ /// This method preserves the underlying buffer storage and does not copy
51
+ /// the payload. It can return fewer bytes than requested, including an
52
+ /// empty buffer at EOF.
53
+ pub fn read_buffer(&mut self, size: usize) -> io::Result<Buffer> {
54
+ let Some(r) = self.r.as_mut() else {
55
+ return Err(Error::new(ErrorKind::Unexpected, "reader has been dropped").into());
56
+ };
57
+
58
+ self.handle.block_on(r.read_buffer(size))
59
+ }
60
+
61
+ /// Read all remaining bytes and return them as an OpenDAL [`Buffer`].
62
+ ///
63
+ /// This method preserves the underlying buffer storage and only allocates
64
+ /// metadata when multiple buffers must be combined.
65
+ pub fn read_to_end_buffer(&mut self) -> io::Result<Buffer> {
66
+ let Some(r) = self.r.as_mut() else {
67
+ return Err(Error::new(ErrorKind::Unexpected, "reader has been dropped").into());
68
+ };
69
+
70
+ self.handle.block_on(r.read_to_end_buffer())
71
+ }
47
72
  }
48
73
 
49
74
  impl BufRead for StdReader {