extent_utils.h revision 14158570d3995008dc93a628004118b87a6bca01
1// Copyright 2015 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_EXTENT_UTILS_H_
6#define UPDATE_ENGINE_PAYLOAD_GENERATOR_EXTENT_UTILS_H_
7
8#include <vector>
9
10#include "update_engine/payload_constants.h"
11#include "update_engine/update_metadata.pb.h"
12
13// Utility functions for manipulating Extents and lists of blocks.
14
15namespace chromeos_update_engine {
16
17// |block| must either be the next block in the last extent or a block
18// in the next extent. This function will not handle inserting block
19// into an arbitrary place in the extents.
20void AppendBlockToExtents(std::vector<Extent>* extents, uint64_t block);
21
22// Get/SetElement are intentionally overloaded so that templated functions
23// can accept either type of collection of Extents.
24Extent GetElement(const std::vector<Extent>& collection, size_t index);
25Extent GetElement(
26    const google::protobuf::RepeatedPtrField<Extent>& collection,
27    size_t index);
28
29// Return the total number of blocks in a collection (vector or
30// RepeatedPtrField) of Extents.
31template<typename T>
32uint64_t BlocksInExtents(const T& collection) {
33  uint64_t ret = 0;
34  for (size_t i = 0; i < static_cast<size_t>(collection.size()); ++i) {
35    ret += GetElement(collection, i).num_blocks();
36  }
37  return ret;
38}
39
40// Takes a collection (vector or RepeatedPtrField) of Extent and
41// returns a vector of the blocks referenced, in order.
42template<typename T>
43std::vector<uint64_t> ExpandExtents(const T& extents) {
44  std::vector<uint64_t> ret;
45  for (size_t i = 0, e = static_cast<size_t>(extents.size()); i != e; ++i) {
46    const Extent extent = GetElement(extents, i);
47    if (extent.start_block() == kSparseHole) {
48      ret.resize(ret.size() + extent.num_blocks(), kSparseHole);
49    } else {
50      for (uint64_t block = extent.start_block();
51           block < (extent.start_block() + extent.num_blocks()); block++) {
52        ret.push_back(block);
53      }
54    }
55  }
56  return ret;
57}
58
59// Stores all Extents in 'extents' into 'out'.
60void StoreExtents(const std::vector<Extent>& extents,
61                  google::protobuf::RepeatedPtrField<Extent>* out);
62
63// Stores all extents in |extents| into |out_vector|.
64void ExtentsToVector(const google::protobuf::RepeatedPtrField<Extent>& extents,
65                     std::vector<Extent>* out_vector);
66
67// Takes a pointer to extents |extents| and extents |extents_to_add|, and
68// merges them by adding |extents_to_add| to |extents| and normalizing.
69void ExtendExtents(
70  google::protobuf::RepeatedPtrField<Extent>* extents,
71  const google::protobuf::RepeatedPtrField<Extent>& extents_to_add);
72
73// Takes a vector of extents and normalizes those extents. Expects the extents
74// to be sorted by start block. E.g. if |extents| is [(1, 2), (3, 5), (10, 2)]
75// then |extents| will be changed to [(1, 7), (10, 2)].
76void NormalizeExtents(std::vector<Extent>* extents);
77
78// Return a subsequence of the list of blocks passed. Both the passed list of
79// blocks |extents| and the return value are expressed as a list of Extent, not
80// blocks. The returned list skips the first |block_offset| blocks from the
81// |extents| and cotains |block_count| blocks (or less if |extents| is shorter).
82std::vector<Extent> ExtentsSublist(const std::vector<Extent>& extents,
83                                   uint64_t block_offset, uint64_t block_count);
84
85bool operator==(const Extent& a, const Extent& b);
86
87}  // namespace chromeos_update_engine
88
89#endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_EXTENT_UTILS_H_
90