| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "commons.h" |
| |
| #ifndef MEMORYBLOCK_H_ |
| #define MEMORYBLOCK_H_ |
| |
| namespace NativeTask { |
| |
| class MemoryPool; |
| |
| class ComparatorForDualPivotSort { |
| private: |
| const char * _base; |
| ComparatorPtr _keyComparator; |
| public: |
| ComparatorForDualPivotSort(const char * base, ComparatorPtr comparator) |
| : _base(base), _keyComparator(comparator) { |
| } |
| |
| inline int operator()(uint32_t lhs, uint32_t rhs) { |
| KVBuffer * left = (KVBuffer *)(_base + lhs); |
| KVBuffer * right = (KVBuffer *)(_base + rhs); |
| return (*_keyComparator)(left->content, left->keyLength, right->content, right->keyLength); |
| } |
| }; |
| |
| class ComparatorForStdSort { |
| private: |
| const char * _base; |
| ComparatorPtr _keyComparator; |
| public: |
| ComparatorForStdSort(const char * base, ComparatorPtr comparator) |
| : _base(base), _keyComparator(comparator) { |
| } |
| |
| public: |
| inline bool operator()(uint32_t lhs, uint32_t rhs) { |
| KVBuffer * left = (KVBuffer *)(_base + lhs); |
| KVBuffer * right = (KVBuffer *)(_base + rhs); |
| int ret = (*_keyComparator)(left->getKey(), left->keyLength, right->getKey(), right->keyLength); |
| return ret < 0; |
| } |
| }; |
| |
| class MemoryBlock { |
| private: |
| char * _base; |
| uint32_t _size; |
| uint32_t _position; |
| std::vector<uint32_t> _kvOffsets; |
| bool _sorted; |
| |
| public: |
| MemoryBlock(char * pos, uint32_t size); |
| |
| char * base() { |
| return _base; |
| } |
| |
| bool sorted() { |
| return _sorted; |
| } |
| |
| KVBuffer * allocateKVBuffer(uint32_t length) { |
| if (length > remainSpace()) { |
| LOG("Unable to allocate kv from memory buffer, length: %d, remain: %d", length, remainSpace()); |
| return NULL; |
| } |
| _sorted = false; |
| _kvOffsets.push_back(_position); |
| char * space = _base + _position; |
| _position += length; |
| return (KVBuffer *)space; |
| } |
| |
| uint32_t remainSpace() const { |
| return _size - _position; |
| } |
| |
| uint32_t getKVCount() { |
| return _kvOffsets.size(); |
| } |
| |
| KVBuffer * getKVBuffer(int index); |
| |
| void sort(SortAlgorithm type, ComparatorPtr comparator); |
| }; |
| //class MemoryBlock |
| |
| class MemBlockIterator { |
| private: |
| MemoryBlock * _memBlock; |
| uint32_t _end; |
| uint32_t _current; |
| KVBuffer * _kvBuffer; |
| |
| public: |
| |
| MemBlockIterator(MemoryBlock * memBlock) |
| : _memBlock(memBlock), _end(0), _current(0), _kvBuffer(NULL) { |
| _end = memBlock->getKVCount(); |
| } |
| |
| KVBuffer * getKVBuffer() { |
| return _kvBuffer; |
| } |
| |
| /** |
| * move to next key/value |
| * 0 on success |
| * 1 on no more |
| */ |
| bool next() { |
| if (_current >= _end) { |
| return false; |
| } |
| this->_kvBuffer = _memBlock->getKVBuffer(_current); |
| ++_current; |
| return true; |
| } |
| }; |
| //class MemoryBlockIterator |
| |
| typedef MemBlockIterator * MemBlockIteratorPtr; |
| |
| class MemBlockComparator { |
| private: |
| ComparatorPtr _keyComparator; |
| |
| public: |
| MemBlockComparator(ComparatorPtr comparator) |
| : _keyComparator(comparator) { |
| } |
| |
| public: |
| bool operator()(const MemBlockIteratorPtr lhs, const MemBlockIteratorPtr rhs) { |
| |
| KVBuffer * left = lhs->getKVBuffer(); |
| KVBuffer * right = rhs->getKVBuffer(); |
| |
| //Treat NULL as infinite MAX, so that we can pop out next value |
| if (NULL == left) { |
| return false; |
| } |
| |
| if (NULL == right) { |
| return true; |
| } |
| |
| return (*_keyComparator)(left->content, left->keyLength, right->content, right->keyLength) < 0; |
| } |
| }; |
| |
| } //namespace NativeTask |
| |
| #endif /* MEMORYBLOCK_H_ */ |