1/**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include "orc/Int128.hh"
20#include "orc/MemoryPool.hh"
21
22#include "Adaptor.hh"
23
24#include <cstdlib>
25#include <iostream>
26#include <string.h>
27
28namespace orc {
29
30 MemoryPool::~MemoryPool() {
31 // PASS
32 }
33
34 class MemoryPoolImpl: public MemoryPool {
35 public:
36 virtual ~MemoryPoolImpl() override;
37
38 char* malloc(uint64_t size) override;
39 void free(char* p) override;
40 };
41
42 char* MemoryPoolImpl::malloc(uint64_t size) {
43 return static_cast<char*>(std::malloc(size));
44 }
45
46 void MemoryPoolImpl::free(char* p) {
47 std::free(p);
48 }
49
50 MemoryPoolImpl::~MemoryPoolImpl() {
51 // PASS
52 }
53
54 template <class T>
55 DataBuffer<T>::DataBuffer(MemoryPool& pool,
56 uint64_t newSize
57 ): memoryPool(pool),
58 buf(nullptr),
59 currentSize(0),
60 currentCapacity(0) {
61 resize(newSize);
62 }
63
64 template <class T>
65 DataBuffer<T>::~DataBuffer(){
66 for(uint64_t i=currentSize; i > 0; --i) {
67 (buf + i - 1)->~T();
68 }
69 if (buf) {
70 memoryPool.free(reinterpret_cast<char*>(buf));
71 }
72 }
73
74 template <class T>
75 void DataBuffer<T>::resize(uint64_t newSize) {
76 reserve(newSize);
77 if (currentSize > newSize) {
78 for(uint64_t i=currentSize; i > newSize; --i) {
79 (buf + i - 1)->~T();
80 }
81 } else if (newSize > currentSize) {
82 for(uint64_t i=currentSize; i < newSize; ++i) {
83 new (buf + i) T();
84 }
85 }
86 currentSize = newSize;
87 }
88
89 template <class T>
90 void DataBuffer<T>::reserve(uint64_t newCapacity){
91 if (newCapacity > currentCapacity || !buf) {
92 if (buf) {
93 T* buf_old = buf;
94 buf = reinterpret_cast<T*>(memoryPool.malloc(sizeof(T) * newCapacity));
95 memcpy(buf, buf_old, sizeof(T) * currentSize);
96 memoryPool.free(reinterpret_cast<char*>(buf_old));
97 } else {
98 buf = reinterpret_cast<T*>(memoryPool.malloc(sizeof(T) * newCapacity));
99 }
100 currentCapacity = newCapacity;
101 }
102 }
103
104 // Specializations for char
105
106 template <>
107 DataBuffer<char>::~DataBuffer(){
108 if (buf) {
109 memoryPool.free(reinterpret_cast<char*>(buf));
110 }
111 }
112
113 template <>
114 void DataBuffer<char>::resize(uint64_t newSize) {
115 reserve(newSize);
116 if (newSize > currentSize) {
117 memset(buf + currentSize, 0, newSize - currentSize);
118 }
119 currentSize = newSize;
120 }
121
122 // Specializations for char*
123
124 template <>
125 DataBuffer<char*>::~DataBuffer(){
126 if (buf) {
127 memoryPool.free(reinterpret_cast<char*>(buf));
128 }
129 }
130
131 template <>
132 void DataBuffer<char*>::resize(uint64_t newSize) {
133 reserve(newSize);
134 if (newSize > currentSize) {
135 memset(buf + currentSize, 0, (newSize - currentSize) * sizeof(char*));
136 }
137 currentSize = newSize;
138 }
139
140 // Specializations for double
141
142 template <>
143 DataBuffer<double>::~DataBuffer(){
144 if (buf) {
145 memoryPool.free(reinterpret_cast<char*>(buf));
146 }
147 }
148
149 template <>
150 void DataBuffer<double>::resize(uint64_t newSize) {
151 reserve(newSize);
152 if (newSize > currentSize) {
153 memset(buf + currentSize, 0, (newSize - currentSize) * sizeof(double));
154 }
155 currentSize = newSize;
156 }
157
158 // Specializations for int64_t
159
160 template <>
161 DataBuffer<int64_t>::~DataBuffer(){
162 if (buf) {
163 memoryPool.free(reinterpret_cast<char*>(buf));
164 }
165 }
166
167 template <>
168 void DataBuffer<int64_t>::resize(uint64_t newSize) {
169 reserve(newSize);
170 if (newSize > currentSize) {
171 memset(buf + currentSize, 0, (newSize - currentSize) * sizeof(int64_t));
172 }
173 currentSize = newSize;
174 }
175
176 // Specializations for uint64_t
177
178 template <>
179 DataBuffer<uint64_t>::~DataBuffer(){
180 if (buf) {
181 memoryPool.free(reinterpret_cast<char*>(buf));
182 }
183 }
184
185 template <>
186 void DataBuffer<uint64_t>::resize(uint64_t newSize) {
187 reserve(newSize);
188 if (newSize > currentSize) {
189 memset(buf + currentSize, 0, (newSize - currentSize) * sizeof(uint64_t));
190 }
191 currentSize = newSize;
192 }
193
194 // Specializations for unsigned char
195
196 template <>
197 DataBuffer<unsigned char>::~DataBuffer(){
198 if (buf) {
199 memoryPool.free(reinterpret_cast<char*>(buf));
200 }
201 }
202
203 template <>
204 void DataBuffer<unsigned char>::resize(uint64_t newSize) {
205 reserve(newSize);
206 if (newSize > currentSize) {
207 memset(buf + currentSize, 0, newSize - currentSize);
208 }
209 currentSize = newSize;
210 }
211
212 #ifdef __clang__
213 #pragma clang diagnostic ignored "-Wweak-template-vtables"
214 #endif
215
216 template class DataBuffer<char>;
217 template class DataBuffer<char*>;
218 template class DataBuffer<double>;
219 template class DataBuffer<Int128>;
220 template class DataBuffer<int64_t>;
221 template class DataBuffer<uint64_t>;
222 template class DataBuffer<unsigned char>;
223
224 #ifdef __clang__
225 #pragma clang diagnostic ignored "-Wexit-time-destructors"
226 #endif
227
228 MemoryPool* getDefaultPool() {
229 static MemoryPoolImpl internal;
230 return &internal;
231 }
232} // namespace orc
233