Pull from FB rev 63ce89e2f2301e6bba44a111cc7d4218022156f6
[folly.git] / folly / detail / GroupVarintDetail.h
1 /*
2  * Copyright 2012 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 #ifndef FOLLY_DETAIL_GROUPVARINTDETAIL_H_
18 #define FOLLY_DETAIL_GROUPVARINTDETAIL_H_
19
20 #include <stddef.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 {
35     kGroupSize = 4,
36     kHeaderSize = 1,
37   };
38 };
39
40 template <>
41 struct GroupVarintTraits<uint64_t> {
42   enum {
43     kGroupSize = 5,
44     kHeaderSize = 2,
45   };
46 };
47
48 template <typename T>
49 class GroupVarintBase {
50  protected:
51   typedef GroupVarintTraits<T> Traits;
52   enum { kHeaderSize = Traits::kHeaderSize };
53
54  public:
55   typedef T type;
56
57   /**
58    * Number of integers encoded / decoded in one pass.
59    */
60   enum { kGroupSize = Traits::kGroupSize };
61
62   /**
63    * Maximum encoded size.
64    */
65   enum { 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
103 #endif /* FOLLY_DETAIL_GROUPVARINTDETAIL_H_ */
104