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}