mirror of https://gitee.com/bigwinds/arangodb
reduce number of mallocs
This commit is contained in:
parent
205736a028
commit
4f6c598c42
|
@ -27,8 +27,9 @@
|
||||||
/// @author Copyright 2013-2013, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2013-2013, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "Basics/random.h"
|
|
||||||
#include "skip-list.h"
|
#include "skip-list.h"
|
||||||
|
#include "Basics/random.h"
|
||||||
|
#include "Basics/Exceptions.h"
|
||||||
|
|
||||||
using namespace triagens::basics;
|
using namespace triagens::basics;
|
||||||
|
|
||||||
|
@ -50,9 +51,11 @@ static int randomHeight (void) {
|
||||||
while (true) { // will be left by return when the right height is found
|
while (true) { // will be left by return when the right height is found
|
||||||
uint32_t r = TRI_UInt32Random();
|
uint32_t r = TRI_UInt32Random();
|
||||||
for (count = 32; count > 0; count--) {
|
for (count = 32; count > 0; count--) {
|
||||||
if (0 != (r & 1UL) || height == TRI_SKIPLIST_MAX_HEIGHT) return height;
|
if (0 != (r & 1UL) || height == TRI_SKIPLIST_MAX_HEIGHT) {
|
||||||
r = r >> 1;
|
return height;
|
||||||
height++;
|
}
|
||||||
|
r = r >> 1;
|
||||||
|
height++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,24 +66,32 @@ static int randomHeight (void) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SkipListNode* SkipList::allocNode (int height) {
|
SkipListNode* SkipList::allocNode (int height) {
|
||||||
SkipListNode* newNode = new SkipListNode();
|
|
||||||
|
|
||||||
newNode->_doc = nullptr;
|
|
||||||
|
|
||||||
if (0 == height) {
|
if (0 == height) {
|
||||||
newNode->_height = randomHeight();
|
height = randomHeight();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
newNode->_height = height;
|
// allocate enough memory for skiplist node plus all the next nodes in one go
|
||||||
|
void* ptr = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(SkipListNode) + sizeof(SkipListNode*) * height, false);
|
||||||
|
|
||||||
|
if (ptr == nullptr) {
|
||||||
|
THROW_OUT_OF_MEMORY_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkipListNode* newNode;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
newNode->_next = new SkipListNode*[newNode->_height];
|
// use placement new
|
||||||
|
newNode = new(ptr) SkipListNode();
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
delete newNode;
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, ptr);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newNode->_doc = nullptr;
|
||||||
|
newNode->_height = height;
|
||||||
|
newNode->_next = reinterpret_cast<SkipListNode**>(static_cast<char*>(ptr) + sizeof(SkipListNode));
|
||||||
|
|
||||||
for (int i = 0; i < newNode->_height; i++) {
|
for (int i = 0; i < newNode->_height; i++) {
|
||||||
newNode->_next[i] = nullptr;
|
newNode->_next[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -100,8 +111,11 @@ void SkipList::freeNode (SkipListNode* node) {
|
||||||
// update memory usage
|
// update memory usage
|
||||||
_memoryUsed -= sizeof(SkipListNode) +
|
_memoryUsed -= sizeof(SkipListNode) +
|
||||||
sizeof(SkipListNode*) * node->_height;
|
sizeof(SkipListNode*) * node->_height;
|
||||||
delete[] node->_next;
|
|
||||||
delete node;
|
// we have used placement new to construct the skiplist node,
|
||||||
|
// so now we have to manually call its dtor and free the underlying memory
|
||||||
|
node->~SkipListNode();
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue