/[svn]/linuxsampler/trunk/src/common/Pool.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/common/Pool.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2335 by persson, Sat Mar 17 06:19:01 2012 UTC revision 2598 by schoenebeck, Fri Jun 6 12:38:54 2014 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 - 2012 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2014 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 61  class RTListBase { Line 61  class RTListBase {
61              #if CONFIG_DEVMODE              #if CONFIG_DEVMODE
62              RTListBase<T1>* list; // list to which this node currently belongs to              RTListBase<T1>* list; // list to which this node currently belongs to
63              #endif // CONFIG_DEVMODE              #endif // CONFIG_DEVMODE
64                int reincarnation; // just for Pool::fromID()
65    
66              _Node() {              _Node() {
67                  next = NULL;                  next = NULL;
# Line 69  class RTListBase { Line 70  class RTListBase {
70                  #if CONFIG_DEVMODE                  #if CONFIG_DEVMODE
71                  list = NULL;                  list = NULL;
72                  #endif // CONFIG_DEVMODE                  #endif // CONFIG_DEVMODE
73                    reincarnation = 0;
74              }              }
75          };          };
76          typedef _Node<T> Node;          typedef _Node<T> Node;
# Line 145  class RTListBase { Line 147  class RTListBase {
147                      }                      }
148                      #endif // CONFIG_DEVMODE                      #endif // CONFIG_DEVMODE
149                      return *current->data;                      return *current->data;
150                    }
151    
152                    inline const T1& operator*() const {
153                        #if CONFIG_DEVMODE
154                        if (!isValid()) { // if iterator became invalidated
155                            #if CONFIG_RT_EXCEPTIONS
156                            throw std::runtime_error(__err_msg_iterator_invalidated);
157                            #else
158                            std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
159                            return *((const T1*)NULL); // force segfault if iterator became invalidated
160                            #endif // CONFIG_RT_EXCEPTIONS
161                        }
162                        #endif // CONFIG_DEVMODE
163                        return *current->data;
164                  }                  }
165    
166                  inline T1* operator->() {                  inline T1* operator->() {
# Line 162  class RTListBase { Line 177  class RTListBase {
177                      return current->data;                      return current->data;
178                  }                  }
179    
180                  inline bool operator==(const _Iterator<T1> other) {                  inline const T1* operator->() const {
181                        #if CONFIG_DEVMODE
182                        if (!isValid()) { // if iterator became invalidated
183                            #if CONFIG_RT_EXCEPTIONS
184                            throw std::runtime_error(__err_msg_iterator_invalidated);
185                            #else
186                            std::cerr << __err_msg_iterator_invalidated << std::endl << std::flush;
187                            return (const T1*)NULL; // force segfault if iterator became invalidated
188                            #endif // CONFIG_RT_EXCEPTIONS
189                        }
190                        #endif // CONFIG_DEVMODE
191                        return current->data;
192                    }
193    
194                    inline bool operator==(const _Iterator<T1> other) const {
195                      return current == other.current;                      return current == other.current;
196                  }                  }
197    
198                  inline bool operator!=(const _Iterator<T1> other) {                  inline bool operator!=(const _Iterator<T1> other) const {
199                      return current != other.current;                      return current != other.current;
200                  }                  }
201    
# Line 195  class RTListBase { Line 224  class RTListBase {
224                  }                  }
225    
226                  #if CONFIG_DEVMODE                  #if CONFIG_DEVMODE
227                  inline bool isValid() {                  inline bool isValid() const {
228                      return current->list == list;                      return current->list == list;
229                  }                  }
230                  #endif // CONFIG_DEVMODE                  #endif // CONFIG_DEVMODE
# Line 232  class RTListBase { Line 261  class RTListBase {
261                      #endif // CONFIG_DEVMODE                      #endif // CONFIG_DEVMODE
262                  }                  }
263    
264                    inline const Node* node() const {
265                        #if CONFIG_DEVMODE
266                        #if CONFIG_RT_EXCEPTIONS
267                        if (isValid()) return current;
268                        else throw std::runtime_error(__err_msg_iterator_invalidated);
269                        #else
270                        return (isValid()) ? current : (const Node*)NULL; // force segfault if iterator became invalidated
271                        #endif // CONFIG_RT_EXCEPTIONS
272                        #else
273                        return current;
274                        #endif // CONFIG_DEVMODE
275                    }
276    
277                  inline void detach() {                  inline void detach() {
278                      RTListBase<T1>::detach(*this);                      RTListBase<T1>::detach(*this);
279                  }                  }
# Line 258  class RTListBase { Line 300  class RTListBase {
300              return Iterator(&_end, Iterator::dir_backward);              return Iterator(&_end, Iterator::dir_backward);
301          }          }
302    
303          inline bool isEmpty() {          inline bool isEmpty() const {
304              return _begin.next == &_end;              return _begin.next == &_end;
305          }          }
306    
# Line 399  class RTList : public RTListBase<T> { Line 441  class RTList : public RTListBase<T> {
441              clear();              clear();
442          }          }
443    
444          inline bool poolIsEmpty() {          inline bool poolIsEmpty() const {
445              return pPool->poolIsEmpty();              return pPool->poolIsEmpty();
446          }          }
447    
# Line 438  class RTList : public RTListBase<T> { Line 480  class RTList : public RTListBase<T> {
480              }              }
481          }          }
482    
483            inline int getID(const T* obj) const {
484                return pPool->getID(obj);
485            }
486    
487            inline int getID(const Iterator& it) const {
488                return pPool->getID(&*it);
489            }
490    
491            inline Iterator fromID(int id) const {
492                return pPool->fromID(id);
493            }
494    
495      protected:      protected:
496          Pool<T>* pPool;          Pool<T>* pPool;
497  };  };
# Line 462  class Pool : public RTList<T> { Line 516  class Pool : public RTList<T> {
516              if (data)  delete[] data;              if (data)  delete[] data;
517          }          }
518    
519          inline bool poolIsEmpty() {          inline bool poolIsEmpty() const {
520              return freelist.isEmpty();              return freelist.isEmpty();
521          }          }
522    
# Line 507  class Pool : public RTList<T> { Line 561  class Pool : public RTList<T> {
561              _init(Elements);              _init(Elements);
562          }          }
563    
564            /**
565             * Returns an abstract, unique numeric ID for the given object of
566             * this pool, it returns -1 in case the passed object is not a member
567             * of this Pool, i.e. because it is simply an invalid pointer or member
568             * of another Pool. The returned ID is unique among all elements of this
569             * Pool and it differs with each reincarnation of an object. That means
570             * each time you free an element to and allocate the same element back
571             * from the Pool, it will have a different ID.
572             *
573             * Members are always translated both, from Iterators/pointers to IDs,
574             * and from IDs to Iterators/pointers in constant time.
575             *
576             * You might want to use this alternative approach of referencing Pool
577             * members under certain scenarios. For example if you need to expose
578             * an ID to the end user and/or if you want to represent an object of
579             * this pool by a smaller number instead of a native pointer (i.e. 16
580             * bits vs. 64 bits). You can also detect this way whether the object
581             * has already been freed / reallocated from the Pool in the meantime.
582             *
583             * @param obj - raw pointer to a data member of this Pool
584             * @returns unique numeric ID of @a obj or -1 if pointer was invalid
585             */
586            int getID(const T* obj) const {
587                if (!poolsize) return -1;
588                int index = obj - &data[0];
589                if (index < 0 || index >= poolsize) return -1;
590                return (nodes[index].reincarnation << bitsForSize(poolsize)) | index;
591            }
592    
593            /**
594             * Overridden convenience method, behaves like the method above.
595             */
596            int getID(const Iterator& it) const {
597                return getID(&*it);
598            }
599    
600            /**
601             * Returns an Iterator object of the Pool data member reflected by the
602             * given abstract, unique numeric ID, it returns an invalid Iterator in
603             * case the ID is invalid or if the Pool's data element reflected by
604             * given ID was at least once released/freed back to the Pool in the
605             * meantime.
606             *
607             * Members are always translated both, from Iterators/pointers to IDs,
608             * and from IDs to Iterators/pointers in constant time.
609             *
610             * You might want to use this alternative approach of referencing Pool
611             * members under certain scenarios. For example if you need to expose
612             * an ID to the end user and/or if you want to represent an object of
613             * this pool by a smaller number instead of a native pointer (i.e. 16
614             * bits vs. 64 bits). You can also detect this way whether the object
615             * has already been freed / reallocated from the Pool in the meantime.
616             *
617             * @param id - unique ID of a Pool's data member
618             * @returns Iterator object pointing to Pool's data element, invalid
619             *          Iterator in case ID was invalid or data element was freed
620             */
621            Iterator fromID(int id) const {
622                if (id < 0) return Iterator(); // invalid iterator
623                const uint bits = bitsForSize(poolsize);
624                uint index = id & ((1 << bits) - 1);
625                if (index >= poolsize) return Iterator(); // invalid iterator
626                Node* node = &nodes[index];
627                int reincarnation = uint(id) >> bits;
628                if (reincarnation != node->reincarnation) return Iterator(); // invalid iterator
629                return Iterator(node);
630            }
631    
632      protected:      protected:
633          // caution: assumes pool (that is freelist) is not empty!          // caution: assumes pool (that is freelist) is not empty!
634          inline Iterator alloc() {          inline Iterator alloc() {
# Line 516  class Pool : public RTList<T> { Line 638  class Pool : public RTList<T> {
638          }          }
639    
640          inline void freeToPool(Iterator itElement) {          inline void freeToPool(Iterator itElement) {
641                itElement.node()->reincarnation++;
642              freelist.append(itElement);              freelist.append(itElement);
643          }          }
644    
645          inline void freeToPool(Iterator itFirst, Iterator itLast) {          inline void freeToPool(Iterator itFirst, Iterator itLast) {
646                for (Node* n = itFirst.node(); true; n = n->next) {
647                    n->reincarnation++;
648                    if (n == itLast.node()) break;
649                }
650              freelist.append(itFirst, itLast);              freelist.append(itFirst, itLast);
651          }          }
652    
# Line 535  class Pool : public RTList<T> { Line 662  class Pool : public RTList<T> {
662              }              }
663              poolsize = Elements;              poolsize = Elements;
664          }          }
665    
666            inline static int bitsForSize(int size) {
667                if (!size) return 0;
668                size--;
669                int bits = 0;
670                for (; size > 1; bits += 2, size >>= 2);
671                return bits + size;
672            }
673  };  };
674    
675  #endif // __LS_POOL_H__  #endif // __LS_POOL_H__

Legend:
Removed from v.2335  
changed lines
  Added in v.2598

  ViewVC Help
Powered by ViewVC