IN2OSM  1.0.1
memory_pool< Ch >

#include <rapidxml.hpp>

Inheritance diagram for memory_pool< Ch >:
Inheritance graph
Collaboration diagram for memory_pool< Ch >:
Collaboration graph

Classes

struct  header
 

Public Member Functions

 memory_pool ()
 Constructs empty pool with default allocator functions. More...
 
 ~memory_pool ()
 
xml_node< Ch > * allocate_node (node_type type, const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
 
xml_attribute< Ch > * allocate_attribute (const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
 
Ch * allocate_string (const Ch *source=0, std::size_t size=0)
 
xml_node< Ch > * clone_node (const xml_node< Ch > *source, xml_node< Ch > *result=0)
 
void clear ()
 
void set_allocator (alloc_func *af, free_func *ff)
 

Private Member Functions

void init ()
 
char * align (char *ptr)
 
char * allocate_raw (std::size_t size)
 
void * allocate_aligned (std::size_t size)
 

Private Attributes

char * m_begin
 
char * m_ptr
 
char * m_end
 
char m_static_memory [RAPIDXML_STATIC_POOL_SIZE]
 
alloc_func * m_alloc_func
 
free_func * m_free_func
 

Detailed Description

template<class Ch = char>
class rapidxml::memory_pool< Ch >

This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation. In most cases, you will not need to use this class directly. However, if you need to create nodes manually or modify names/values of nodes, you are encouraged to use memory_pool of relevant xml_document to allocate the memory. Not only is this faster than allocating them by using new operator, but also their lifetime will be tied to the lifetime of document, possibly simplyfing memory management.

Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. You can also call allocate_string() function to allocate strings. Such strings can then be used as names or values of nodes without worrying about their lifetime. Note that there is no free() function – all allocations are freed at once when clear() function is called, or when the pool is destroyed.

It is also possible to create a standalone memory_pool, and use it to allocate nodes, whose lifetime will not be tied to any document.

Pool maintains RAPIDXML_STATIC_POOL_SIZE bytes of statically allocated memory. Until static memory is exhausted, no dynamic memory allocations are done. When static memory is exhausted, pool allocates additional blocks of memory of size RAPIDXML_DYNAMIC_POOL_SIZE each, by using global new[] and delete[] operators. This behaviour can be changed by setting custom allocation routines. Use set_allocator() function to set them.

Allocations for nodes, attributes and strings are aligned at RAPIDXML_ALIGNMENT bytes. This value defaults to the size of pointer on target architecture.

To obtain absolutely top performance from the parser, it is important that all nodes are allocated from a single, contiguous block of memory. Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably. If required, you can tweak RAPIDXML_STATIC_POOL_SIZE, RAPIDXML_DYNAMIC_POOL_SIZE and RAPIDXML_ALIGNMENT to obtain best wasted memory to performance compromise. To do it, define their values before rapidxml.hpp file is included.

Parameters
ChCharacter type of created nodes.

Definition at line 379 of file rapidxml.hpp.

Constructor & Destructor Documentation

◆ memory_pool()

memory_pool ( )
inline

Constructs empty pool with default allocator functions.

Definition at line 390 of file rapidxml.hpp.

391  : m_alloc_func(0)
392  , m_free_func(0)
393  {
394  init();
395  }
alloc_func * m_alloc_func
Definition: rapidxml.hpp:637
free_func * m_free_func
Definition: rapidxml.hpp:638

◆ ~memory_pool()

~memory_pool ( )
inline

Destroys pool and frees all the memory. This causes memory occupied by nodes allocated by the pool to be freed. Nodes allocated from the pool are no longer valid.

Definition at line 400 of file rapidxml.hpp.

401  {
402  clear();
403  }

Member Function Documentation

◆ align()

char* align ( char *  ptr)
inlineprivate

Definition at line 573 of file rapidxml.hpp.

574  {
575  std::size_t alignment = ((RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1))) & (RAPIDXML_ALIGNMENT - 1));
576  return ptr + alignment;
577  }
#define RAPIDXML_ALIGNMENT
Definition: rapidxml.hpp:131

◆ allocate_aligned()

void* allocate_aligned ( std::size_t  size)
inlineprivate

Definition at line 599 of file rapidxml.hpp.

600  {
601  // Calculate aligned pointer
602  char *result = align(m_ptr);
603 
604  // If not enough memory left in current pool, allocate a new pool
605  if (result + size > m_end)
606  {
607  // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE)
608  std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE;
609  if (pool_size < size)
610  pool_size = size;
611 
612  // Allocate
613  std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation
614  char *raw_memory = allocate_raw(alloc_size);
615 
616  // Setup new pool in allocated memory
617  char *pool = align(raw_memory);
618  header *new_header = reinterpret_cast<header *>(pool);
619  new_header->previous_begin = m_begin;
620  m_begin = raw_memory;
621  m_ptr = pool + sizeof(header);
622  m_end = raw_memory + alloc_size;
623 
624  // Calculate aligned pointer again using new pool
625  result = align(m_ptr);
626  }
627 
628  // Update pool and return aligned pointer
629  m_ptr = result + size;
630  return result;
631  }
#define RAPIDXML_DYNAMIC_POOL_SIZE
Definition: rapidxml.hpp:123
char * allocate_raw(std::size_t size)
Definition: rapidxml.hpp:579
#define RAPIDXML_ALIGNMENT
Definition: rapidxml.hpp:131
char * align(char *ptr)
Definition: rapidxml.hpp:573

◆ allocate_attribute()

xml_attribute<Ch>* allocate_attribute ( const Ch *  name = 0,
const Ch *  value = 0,
std::size_t  name_size = 0,
std::size_t  value_size = 0 
)
inline

Allocates a new attribute from the pool, and optionally assigns name and value to it. If the allocation request cannot be accomodated, this function will throw std::bad_alloc. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function.

Parameters
nameName to assign to the attribute, or 0 to assign no name.
valueValue to assign to the attribute, or 0 to assign no value.
name_sizeSize of name to assign, or 0 to automatically calculate size from name string.
value_sizeSize of value to assign, or 0 to automatically calculate size from value string.
Returns
Pointer to allocated attribute. This pointer will never be NULL.

Definition at line 447 of file rapidxml.hpp.

449  {
450  void *memory = allocate_aligned(sizeof(xml_attribute<Ch>));
451  xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>;
452  if (name)
453  {
454  if (name_size > 0)
455  attribute->name(name, name_size);
456  else
457  attribute->name(name);
458  }
459  if (value)
460  {
461  if (value_size > 0)
462  attribute->value(value, value_size);
463  else
464  attribute->value(value);
465  }
466  return attribute;
467  }
void * allocate_aligned(std::size_t size)
Definition: rapidxml.hpp:599
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
Here is the call graph for this function:
Here is the caller graph for this function:

◆ allocate_node()

xml_node<Ch>* allocate_node ( node_type  type,
const Ch *  name = 0,
const Ch *  value = 0,
std::size_t  name_size = 0,
std::size_t  value_size = 0 
)
inline

Allocates a new node from the pool, and optionally assigns name and value to it. If the allocation request cannot be accomodated, this function will throw std::bad_alloc. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function.

Parameters
typeType of node to create.
nameName to assign to the node, or 0 to assign no name.
valueValue to assign to the node, or 0 to assign no value.
name_sizeSize of name to assign, or 0 to automatically calculate size from name string.
value_sizeSize of value to assign, or 0 to automatically calculate size from value string.
Returns
Pointer to allocated node. This pointer will never be NULL.

Definition at line 415 of file rapidxml.hpp.

418  {
419  void *memory = allocate_aligned(sizeof(xml_node<Ch>));
420  xml_node<Ch> *node = new(memory) xml_node<Ch>(type);
421  if (name)
422  {
423  if (name_size > 0)
424  node->name(name, name_size);
425  else
426  node->name(name);
427  }
428  if (value)
429  {
430  if (value_size > 0)
431  node->value(value, value_size);
432  else
433  node->value(value);
434  }
435  return node;
436  }
void * allocate_aligned(std::size_t size)
Definition: rapidxml.hpp:599
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
Here is the call graph for this function:
Here is the caller graph for this function:

◆ allocate_raw()

char* allocate_raw ( std::size_t  size)
inlineprivate

Definition at line 579 of file rapidxml.hpp.

580  {
581  // Allocate
582  void *memory;
583  if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[]
584  {
585  memory = m_alloc_func(size);
586  assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp
587  }
588  else
589  {
590  memory = new char[size];
591 #ifdef RAPIDXML_NO_EXCEPTIONS
592  if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc
593  RAPIDXML_PARSE_ERROR("out of memory", 0);
594 #endif
595  }
596  return static_cast<char *>(memory);
597  }
#define RAPIDXML_PARSE_ERROR(what, where)
Definition: rapidxml.hpp:55
alloc_func * m_alloc_func
Definition: rapidxml.hpp:637

◆ allocate_string()

Ch* allocate_string ( const Ch *  source = 0,
std::size_t  size = 0 
)
inline

Allocates a char array of given size from the pool, and optionally copies a given string to it. If the allocation request cannot be accomodated, this function will throw std::bad_alloc. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function.

Parameters
sourceString to initialize the allocated memory with, or 0 to not initialize it.
sizeNumber of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated.
Returns
Pointer to allocated char array. This pointer will never be NULL.

Definition at line 476 of file rapidxml.hpp.

477  {
478  assert(source || size); // Either source or size (or both) must be specified
479  if (size == 0)
480  size = internal::measure(source) + 1;
481  Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
482  if (source)
483  for (std::size_t i = 0; i < size; ++i)
484  result[i] = source[i];
485  return result;
486  }
const CharType(& source)[N]
Definition: pointer.h:1204
void * allocate_aligned(std::size_t size)
Definition: rapidxml.hpp:599
Here is the caller graph for this function:

◆ clear()

void clear ( )
inline

Clears the pool. This causes memory occupied by nodes allocated by the pool to be freed. Any nodes or strings allocated from the pool will no longer be valid.

Definition at line 525 of file rapidxml.hpp.

526  {
527  while (m_begin != m_static_memory)
528  {
529  char *previous_begin = reinterpret_cast<header *>(align(m_begin))->previous_begin;
530  if (m_free_func)
532  else
533  delete[] m_begin;
534  m_begin = previous_begin;
535  }
536  init();
537  }
char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]
Definition: rapidxml.hpp:636
char * align(char *ptr)
Definition: rapidxml.hpp:573
free_func * m_free_func
Definition: rapidxml.hpp:638
Here is the caller graph for this function:

◆ clone_node()

xml_node<Ch>* clone_node ( const xml_node< Ch > *  source,
xml_node< Ch > *  result = 0 
)
inline

Clones an xml_node and its hierarchy of child nodes and attributes. Nodes and attributes are allocated from this memory pool. Names and values are not cloned, they are shared between the clone and the source. Result node can be optionally specified as a second parameter, in which case its contents will be replaced with cloned source node. This is useful when you want to clone entire document.

Parameters
sourceNode to clone.
resultNode to put results in, or 0 to automatically allocate result node
Returns
Pointer to cloned node. This pointer will never be NULL.

Definition at line 497 of file rapidxml.hpp.

498  {
499  // Prepare result node
500  if (result)
501  {
502  result->remove_all_attributes();
503  result->remove_all_nodes();
504  result->type(source->type());
505  }
506  else
507  result = allocate_node(source->type());
508 
509  // Clone name and value
510  result->name(source->name(), source->name_size());
511  result->value(source->value(), source->value_size());
512 
513  // Clone child nodes and attributes
514  for (xml_node<Ch> *child = source->first_node(); child; child = child->next_sibling())
515  result->append_node(clone_node(child));
516  for (xml_attribute<Ch> *attr = source->first_attribute(); attr; attr = attr->next_attribute())
517  result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size()));
518 
519  return result;
520  }
xml_node< Ch > * allocate_node(node_type type, const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
Definition: rapidxml.hpp:415
const CharType(& source)[N]
Definition: pointer.h:1204
xml_node< Ch > * clone_node(const xml_node< Ch > *source, xml_node< Ch > *result=0)
Definition: rapidxml.hpp:497
xml_attribute< Ch > * allocate_attribute(const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
Definition: rapidxml.hpp:447
Here is the call graph for this function:

◆ init()

void init ( )
inlineprivate

Definition at line 566 of file rapidxml.hpp.

567  {
569  m_ptr = align(m_begin);
571  }
char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]
Definition: rapidxml.hpp:636
char * align(char *ptr)
Definition: rapidxml.hpp:573

◆ set_allocator()

void set_allocator ( alloc_func *  af,
free_func *  ff 
)
inline

Sets or resets the user-defined memory allocation functions for the pool. This can only be called when no memory is allocated from the pool yet, otherwise results are undefined. Allocation function must not return invalid pointer on failure. It should either throw, stop the program, or use longjmp() function to pass control to other place of program. If it returns invalid pointer, results are undefined.

User defined allocation functions must have the following forms:

void *allocate(std::size_t size);
void free(void *pointer);

Parameters
afAllocation function, or 0 to restore default function
ffFree function, or 0 to restore default function

Definition at line 552 of file rapidxml.hpp.

553  {
554  assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet
555  m_alloc_func = af;
556  m_free_func = ff;
557  }
char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]
Definition: rapidxml.hpp:636
char * align(char *ptr)
Definition: rapidxml.hpp:573
alloc_func * m_alloc_func
Definition: rapidxml.hpp:637
free_func * m_free_func
Definition: rapidxml.hpp:638

Member Data Documentation

◆ m_alloc_func

alloc_func* m_alloc_func
private

Definition at line 637 of file rapidxml.hpp.

◆ m_begin

char* m_begin
private

Definition at line 633 of file rapidxml.hpp.

◆ m_end

char* m_end
private

Definition at line 635 of file rapidxml.hpp.

◆ m_free_func

free_func* m_free_func
private

Definition at line 638 of file rapidxml.hpp.

◆ m_ptr

char* m_ptr
private

Definition at line 634 of file rapidxml.hpp.

◆ m_static_memory

char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]
private

Definition at line 636 of file rapidxml.hpp.


The documentation for this class was generated from the following file: