1 | /* |
2 | * Copyright 2012-present Facebook, Inc. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #pragma once |
18 | |
19 | #include <stddef.h> |
20 | #include <stdint.h> |
21 | |
22 | namespace folly { |
23 | |
24 | template <typename T> |
25 | class GroupVarint; |
26 | |
27 | namespace detail { |
28 | |
29 | template <typename T> |
30 | struct GroupVarintTraits; |
31 | |
32 | template <> |
33 | struct GroupVarintTraits<uint32_t> { |
34 | enum : uint32_t { |
35 | kGroupSize = 4, |
36 | = 1, |
37 | }; |
38 | }; |
39 | |
40 | template <> |
41 | struct GroupVarintTraits<uint64_t> { |
42 | enum : uint32_t { |
43 | kGroupSize = 5, |
44 | = 2, |
45 | }; |
46 | }; |
47 | |
48 | template <typename T> |
49 | class GroupVarintBase { |
50 | protected: |
51 | typedef GroupVarintTraits<T> Traits; |
52 | enum : uint32_t { = Traits::kHeaderSize }; |
53 | |
54 | public: |
55 | typedef T type; |
56 | |
57 | /** |
58 | * Number of integers encoded / decoded in one pass. |
59 | */ |
60 | enum : uint32_t { kGroupSize = Traits::kGroupSize }; |
61 | |
62 | /** |
63 | * Maximum encoded size. |
64 | */ |
65 | enum : uint32_t { kMaxSize = kHeaderSize + sizeof(type) * kGroupSize }; |
66 | |
67 | /** |
68 | * Maximum size for n values. |
69 | */ |
70 | static size_t maxSize(size_t n) { |
71 | // Full groups |
72 | size_t total = (n / kGroupSize) * kFullGroupSize; |
73 | // Incomplete last group, if any |
74 | n %= kGroupSize; |
75 | if (n) { |
76 | total += kHeaderSize + n * sizeof(type); |
77 | } |
78 | return total; |
79 | } |
80 | |
81 | /** |
82 | * Size of n values starting at p. |
83 | */ |
84 | static size_t totalSize(const T* p, size_t n) { |
85 | size_t size = 0; |
86 | for (; n >= kGroupSize; n -= kGroupSize, p += kGroupSize) { |
87 | size += Derived::size(p); |
88 | } |
89 | if (n) { |
90 | size += Derived::partialSize(p, n); |
91 | } |
92 | return size; |
93 | } |
94 | |
95 | private: |
96 | typedef GroupVarint<T> Derived; |
97 | enum { kFullGroupSize = kHeaderSize + kGroupSize * sizeof(type) }; |
98 | }; |
99 | |
100 | } // namespace detail |
101 | } // namespace folly |
102 | |