blob: eeeed403083d5bd4a96e47108e802f9813339b8b [file] [log] [blame]
Alex Deymo5c6c6552015-06-03 19:06:50 +02001// 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
Alex Deymo14158572015-06-13 03:37:08 -070010#include "update_engine/payload_constants.h"
Alex Deymo5c6c6552015-06-03 19:06:50 +020011#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
Alex Deymo14158572015-06-13 03:37:08 -070029// Return the total number of blocks in a collection (vector or
30// RepeatedPtrField) of Extents.
Alex Deymo5c6c6552015-06-03 19:06:50 +020031template<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
Alex Deymo14158572015-06-13 03:37:08 -070040// 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
Alex Deymo52490e72015-06-04 14:53:44 +020073// 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
Alex Deymo5c6c6552015-06-03 19:06:50 +020085bool operator==(const Extent& a, const Extent& b);
86
87} // namespace chromeos_update_engine
88
89#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_EXTENT_UTILS_H_