Skip to content

Commit

Permalink
allocate node cache in one big chunk instead of small pieces
Browse files Browse the repository at this point in the history
* malloc() will allocated it using mmap() instead of using the heap
  so that it can be free()d right away without heap fragmentation
  issues

* less malloc()/free() overhead as there is only one call in total
  instead of one for each node block

* no calloc() overhead on startup
  • Loading branch information
hholzgra committed Aug 17, 2011
1 parent c2c307d commit 9f05f1b
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions middle-pgsql.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ static struct ramNodeBlock blocks[NUM_BLOCKS];
static int usedBlocks;
/* Note: maxBlocks *must* be odd, to make sure the priority queue has no nodes with only one child */
static int maxBlocks = 0;
static void *blockCache = NULL;
static struct ramNodeBlock **queue;
static osmid_t storedNodes, totalNodes;
int nodesCacheHits, nodesCacheLookups;
Expand Down Expand Up @@ -226,6 +227,18 @@ static void percolate_up( int pos )
}
}

static void *next_chunk(size_t count, size_t size)
{
static size_t pos = 0;
void *result;

result = blockCache + pos;

pos += count * size;

return result;
}

#define UNUSED __attribute__ ((unused))
static int pgsql_ram_nodes_set(osmid_t id, double lat, double lon, struct keyval *tags UNUSED)
{
Expand All @@ -242,7 +255,8 @@ static int pgsql_ram_nodes_set(osmid_t id, double lat, double lon, struct keyval
/* Upto log(usedBlocks) iterations */
percolate_up( usedBlocks-1 );

blocks[block].nodes = calloc(PER_BLOCK, sizeof(struct ramNode));
blocks[block].nodes = next_chunk(PER_BLOCK, sizeof(struct ramNode));

blocks[block].used = 0;
if (!blocks[block].nodes) {
fprintf(stderr, "Error allocating nodes\n");
Expand Down Expand Up @@ -1277,7 +1291,13 @@ static int pgsql_start(const struct output_options *options)
/* How much we can fit, and make sure it's odd */
maxBlocks = (options->cache*((1024*1024)/(PER_BLOCK*sizeof(struct ramNode)))) | 1;
queue = malloc( maxBlocks * sizeof(struct ramNodeBlock) );

blockCache = malloc(maxBlocks * PER_BLOCK * sizeof(struct ramNode));

if (!queue || !blockCache) {
fprintf(stderr, "Out of memory, reduce --cache size\n");
exit_nicely();
}

#ifdef __MINGW_H
fprintf( stderr, "Mid: pgsql, scale=%d, cache=%dMB, maxblocks=%d*%d\n", scale, options->cache, maxBlocks, PER_BLOCK*sizeof(struct ramNode) );
#else
Expand Down Expand Up @@ -1441,11 +1461,7 @@ static void pgsql_stop(void)
storedNodes, 100.0f*storedNodes/totalNodes, 100.0f*storedNodes/(usedBlocks*PER_BLOCK),
100.0f*nodesCacheHits/nodesCacheLookups );

for( i=0; i<usedBlocks; i++ )
{
free(queue[i]->nodes);
queue[i]->nodes = NULL;
}
free(blockCache);
free(queue);

#ifdef HAVE_PTHREAD
Expand Down

0 comments on commit 9f05f1b

Please sign in to comment.