github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/flann/allocator.h (about)

     1  /***********************************************************************
     2   * Software License Agreement (BSD License)
     3   *
     4   * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
     5   * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
     6   *
     7   * THE BSD LICENSE
     8   *
     9   * Redistribution and use in source and binary forms, with or without
    10   * modification, are permitted provided that the following conditions
    11   * are met:
    12   *
    13   * 1. Redistributions of source code must retain the above copyright
    14   *    notice, this list of conditions and the following disclaimer.
    15   * 2. Redistributions in binary form must reproduce the above copyright
    16   *    notice, this list of conditions and the following disclaimer in the
    17   *    documentation and/or other materials provided with the distribution.
    18   *
    19   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    20   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    21   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    22   * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    23   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    24   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    28   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29   *************************************************************************/
    30  
    31  #ifndef OPENCV_FLANN_ALLOCATOR_H_
    32  #define OPENCV_FLANN_ALLOCATOR_H_
    33  
    34  //! @cond IGNORED
    35  
    36  #include <stdlib.h>
    37  #include <stdio.h>
    38  
    39  
    40  namespace cvflann
    41  {
    42  
    43  /**
    44   * Allocates (using C's malloc) a generic type T.
    45   *
    46   * Params:
    47   *     count = number of instances to allocate.
    48   * Returns: pointer (of type T*) to memory buffer
    49   */
    50  template <typename T>
    51  T* allocate(size_t count = 1)
    52  {
    53      T* mem = (T*) ::malloc(sizeof(T)*count);
    54      return mem;
    55  }
    56  
    57  
    58  /**
    59   * Pooled storage allocator
    60   *
    61   * The following routines allow for the efficient allocation of storage in
    62   * small chunks from a specified pool.  Rather than allowing each structure
    63   * to be freed individually, an entire pool of storage is freed at once.
    64   * This method has two advantages over just using malloc() and free().  First,
    65   * it is far more efficient for allocating small objects, as there is
    66   * no overhead for remembering all the information needed to free each
    67   * object or consolidating fragmented memory.  Second, the decision about
    68   * how long to keep an object is made at the time of allocation, and there
    69   * is no need to track down all the objects to free them.
    70   *
    71   */
    72  
    73  const size_t     WORDSIZE=16;
    74  const  size_t     BLOCKSIZE=8192;
    75  
    76  class PooledAllocator
    77  {
    78      /* We maintain memory alignment to word boundaries by requiring that all
    79          allocations be in multiples of the machine wordsize.  */
    80      /* Size of machine word in bytes.  Must be power of 2. */
    81      /* Minimum number of bytes requested at a time from	the system.  Must be multiple of WORDSIZE. */
    82  
    83  
    84      int     remaining;  /* Number of bytes left in current block of storage. */
    85      void*   base;     /* Pointer to base of current block of storage. */
    86      void*   loc;      /* Current location in block to next allocate memory. */
    87      int     blocksize;
    88  
    89  
    90  public:
    91      int     usedMemory;
    92      int     wastedMemory;
    93  
    94      /**
    95          Default constructor. Initializes a new pool.
    96       */
    97      PooledAllocator(int blockSize = BLOCKSIZE)
    98      {
    99          blocksize = blockSize;
   100          remaining = 0;
   101          base = NULL;
   102          loc = NULL;
   103  
   104          usedMemory = 0;
   105          wastedMemory = 0;
   106      }
   107  
   108      /**
   109       * Destructor. Frees all the memory allocated in this pool.
   110       */
   111      ~PooledAllocator()
   112      {
   113          void* prev;
   114  
   115          while (base != NULL) {
   116              prev = *((void**) base); /* Get pointer to prev block. */
   117              ::free(base);
   118              base = prev;
   119          }
   120      }
   121  
   122      /**
   123       * Returns a pointer to a piece of new memory of the given size in bytes
   124       * allocated from the pool.
   125       */
   126      void* allocateMemory(int size)
   127      {
   128          int blockSize;
   129  
   130          /* Round size up to a multiple of wordsize.  The following expression
   131              only works for WORDSIZE that is a power of 2, by masking last bits of
   132              incremented size to zero.
   133           */
   134          size = (size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
   135  
   136          /* Check whether a new block must be allocated.  Note that the first word
   137              of a block is reserved for a pointer to the previous block.
   138           */
   139          if (size > remaining) {
   140  
   141              wastedMemory += remaining;
   142  
   143              /* Allocate new storage. */
   144              blockSize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ?
   145                          size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE;
   146  
   147              // use the standard C malloc to allocate memory
   148              void* m = ::malloc(blockSize);
   149              if (!m) {
   150                  fprintf(stderr,"Failed to allocate memory.\n");
   151                  return NULL;
   152              }
   153  
   154              /* Fill first word of new block with pointer to previous block. */
   155              ((void**) m)[0] = base;
   156              base = m;
   157  
   158              int shift = 0;
   159              //int shift = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1);
   160  
   161              remaining = blockSize - sizeof(void*) - shift;
   162              loc = ((char*)m + sizeof(void*) + shift);
   163          }
   164          void* rloc = loc;
   165          loc = (char*)loc + size;
   166          remaining -= size;
   167  
   168          usedMemory += size;
   169  
   170          return rloc;
   171      }
   172  
   173      /**
   174       * Allocates (using this pool) a generic type T.
   175       *
   176       * Params:
   177       *     count = number of instances to allocate.
   178       * Returns: pointer (of type T*) to memory buffer
   179       */
   180      template <typename T>
   181      T* allocate(size_t count = 1)
   182      {
   183          T* mem = (T*) this->allocateMemory((int)(sizeof(T)*count));
   184          return mem;
   185      }
   186  
   187  private:
   188      PooledAllocator(const PooledAllocator &); // copy disabled
   189      PooledAllocator& operator=(const PooledAllocator &); // assign disabled
   190  };
   191  
   192  }
   193  
   194  //! @endcond
   195  
   196  #endif //OPENCV_FLANN_ALLOCATOR_H_