object_store/client/parts.rs
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
18use crate::multipart::PartId;
19use parking_lot::Mutex;
20
21/// An interior mutable collection of upload parts and their corresponding part index
22#[derive(Debug, Default)]
23pub(crate) struct Parts(Mutex<Vec<(usize, PartId)>>);
24
25impl Parts {
26 /// Record the [`PartId`] for a given index
27 ///
28 /// Note: calling this method multiple times with the same `part_idx`
29 /// will result in multiple [`PartId`] in the final output
30 pub(crate) fn put(&self, part_idx: usize, id: PartId) {
31 self.0.lock().push((part_idx, id))
32 }
33
34 /// Produce the final list of [`PartId`] ordered by `part_idx`
35 ///
36 /// `expected` is the number of parts expected in the final result
37 pub(crate) fn finish(&self, expected: usize) -> crate::Result<Vec<PartId>> {
38 let mut parts = self.0.lock();
39 if parts.len() != expected {
40 return Err(crate::Error::Generic {
41 store: "Parts",
42 source: "Missing part".to_string().into(),
43 });
44 }
45 parts.sort_unstable_by_key(|(idx, _)| *idx);
46 Ok(parts.drain(..).map(|(_, v)| v).collect())
47 }
48}