ucommon
memory.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU uCommon C++.
4 //
5 // GNU uCommon C++ is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU uCommon C++ is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17 
30 #ifndef _UCOMMON_MEMORY_H_
31 #define _UCOMMON_MEMORY_H_
32 
33 #ifndef _UCOMMON_CONFIG_H_
34 #include <ucommon/platform.h>
35 #endif
36 
37 #ifndef _UCOMMON_PROTOCOLS_H_
38 #include <ucommon/protocols.h>
39 #endif
40 
41 #ifndef _UCOMMON_LINKED_H_
42 #include <ucommon/linked.h>
43 #endif
44 
45 NAMESPACE_UCOMMON
46 
47 class PagerPool;
48 
56 class __EXPORT memalloc : public MemoryProtocol, protected LockingProtocol
57 {
58 private:
59  friend class bufpager;
60 
61  size_t pagesize, align;
62  unsigned count;
63 
64  typedef struct mempage {
65  struct mempage *next;
66  union {
67  void *memalign;
68  unsigned used;
69  };
70  } page_t;
71 
72  page_t *page;
73 
74 protected:
75  unsigned limit;
76 
81  page_t *pager(void);
82 
83 public:
88  memalloc(size_t page = 0);
89 
93  virtual ~memalloc();
94 
99  inline unsigned getPages(void)
100  {return count;};
101 
109  inline unsigned getLimit(void)
110  {return limit;};
111 
116  inline unsigned getAlloc(void)
117  {return pagesize;};
118 
129  unsigned utilization(void);
130 
134  void purge(void);
135 
143  virtual void *_alloc(size_t size);
144 };
145 
166 class __EXPORT mempager : public memalloc
167 {
168 private:
169  pthread_mutex_t mutex;
170 
171 protected:
178  virtual void _lock(void);
179 
183  virtual void _unlock(void);
184 
185 public:
190  mempager(size_t page = 0);
191 
195  virtual ~mempager();
196 
207  unsigned utilization(void);
208 
212  void purge(void);
213 
221  virtual void dealloc(void *memory);
222 
231  virtual void *_alloc(size_t size);
232 };
233 
239 class __EXPORT stringpager : protected memalloc
240 {
241 private:
242  unsigned members;
243  LinkedObject *root;
244 
245 public:
252  class __EXPORT member : public LinkedObject
253  {
254  private:
255  const char *text;
256 
257  protected:
258  friend class stringpager;
259 
260  inline void set(member *node)
261  {next = node;};
262 
263  member(LinkedObject **root, const char *data);
264  member(const char *data);
265 
266  public:
267  inline const char *operator*() const
268  {return text;};
269 
270  inline const char *get(void) const
271  {return text;};
272  };
273 
278  stringpager(size_t pagesize = 256);
279 
284  inline unsigned count(void)
285  {return members;};
286 
293  const char *get(unsigned item);
294 
299  void add(const char *text);
300 
306  void add(char **list);
307 
312  void clear(void);
313 
320  inline const char *operator[](unsigned item)
321  {return get(item);};
322 
328  inline stringpager::member *begin(void)
329  {return static_cast<stringpager::member *>(root);};
330 
335  inline void operator+=(const char *text)
336  {add(text);};
337 
342  inline stringpager& operator<<(const char *text)
343  {add(text); return *this;};
344 
348  void sort(void);
349 
350 private:
351  member *last;
352 };
353 
361 class __EXPORT DirPager : protected stringpager
362 {
363 protected:
364  const char *dir;
365 
371  virtual bool filter(const char *filename);
372 
378  bool load(const char *path);
379 
380 public:
381  DirPager();
382 
383  DirPager(const char *path);
384 
385  void operator=(const char *path);
386 
387  inline const char *operator*()
388  {return dir;};
389 
390  inline operator bool()
391  {return dir != NULL;};
392 
393  inline bool operator!()
394  {return dir == NULL;};
395 
402  inline const char *operator[](unsigned item)
403  {return stringpager::get(item);};
404 
405  inline const char *get(unsigned item)
406  {return stringpager::get(item);};
407 };
408 
413 class __EXPORT bufpager : public memalloc, public CharacterProtocol
414 {
415 private:
416  typedef struct cpage {
417  struct cpage *next;
418  char *text;
419  unsigned size, used;
420  } cpage_t;
421 
422  cpage_t *first, *last, *current, *freelist;
423  unsigned cpos;
424  unsigned long ccount;
425 
426  virtual int _getch(void);
427  virtual int _putch(int code);
428 
429 protected:
430  virtual void *_alloc(size_t size);
431 
432 public:
436  void reset(void);
437 
441  void rewind(void);
442 
447  inline unsigned long getUsed(void)
448  {return ccount;};
449 
450  bufpager(size_t page = 0);
451 };
452 
460 class __EXPORT autorelease
461 {
462 private:
463  LinkedObject *pool;
464 
465 public:
469  autorelease();
470 
474  ~autorelease();
475 
481  void release(void);
482 
487  void operator+=(LinkedObject *object);
488 };
489 
500 class __EXPORT PagerObject : public LinkedObject, public CountedObject
501 {
502 protected:
503  friend class PagerPool;
504 
505  PagerPool *pager;
506 
510  PagerObject();
511 
515  void release(void);
516 
520  void dealloc(void);
521 };
522 
531 class __EXPORT PagerPool : public MemoryProtocol
532 {
533 private:
534  LinkedObject *freelist;
535  pthread_mutex_t mutex;
536 
537 protected:
538  PagerPool();
539  virtual ~PagerPool();
540 
541  PagerObject *get(size_t size);
542 
543 public:
548  void put(PagerObject *object);
549 };
550 
551 class __EXPORT charmem : public CharacterProtocol
552 {
553 protected:
554  char *buffer;
555  size_t inp, out, size;
556  bool dynamic;
557 
558  int _getch(void);
559  int _putch(int code);
560 
561 public:
562  charmem(char *mem, size_t size);
563  charmem(size_t size);
564  charmem();
565  virtual ~charmem();
566 
567  void release(void);
568 
569  void set(char *mem, size_t size);
570 
571  void set(size_t size);
572 
573  inline void reset(void)
574  {inp = out = 0;}
575 
576  inline void rewind(void)
577  {inp = 0;}
578 };
579 
580 class __EXPORT chartext : public CharacterProtocol
581 {
582 private:
583  char *pos;
584  size_t max;
585 
586  int _putch(int code);
587  int _getch(void);
588 
589 public:
590  chartext();
591  chartext(char *buf);
592  chartext(char *buf, size_t size);
593  virtual ~chartext();
594 };
595 
607 class __EXPORT keyassoc : protected mempager
608 {
609 private:
613  class __LOCAL keydata : public NamedObject
614  {
615  public:
616  void *data;
617  char text[8];
618 
619  keydata(keyassoc *assoc, char *id, unsigned max, unsigned bufsize);
620  };
621 
622  friend class keydata;
623 
624  unsigned count;
625  unsigned paths;
626  size_t keysize;
627  NamedObject **root;
628  LinkedObject **list;
629 
630 public:
637  keyassoc(unsigned indexing = 177, size_t max = 0, size_t page = 0);
638 
642  ~keyassoc();
643 
648  inline unsigned getCount(void)
649  {return count;};
650 
656  inline void *operator()(const char *name)
657  {return locate(name);};
658 
662  void purge(void);
663 
669  void *locate(const char *name);
670 
678  bool assign(char *name, void *pointer);
679 
686  bool create(char *name, void *pointer);
687 
694  void *remove(const char *name);
695 };
696 
704 template <class T, unsigned I = 177, size_t M = 0, size_t P = 0>
705 class assoc_pointer : private keyassoc
706 {
707 public:
711  inline assoc_pointer() : keyassoc(I, M, P) {};
712 
717  inline unsigned getCount(void)
718  {return keyassoc::getCount();};
719 
723  inline void purge(void)
724  {keyassoc::purge();};
725 
731  inline T *locate(const char *name)
732  {return static_cast<T*>(keyassoc::locate(name));};
733 
739  inline T *operator()(const char *name)
740  {return locate(name);};
741 
749  inline bool assign(char *name, T *pointer)
750  {return keyassoc::assign(name, pointer);};
751 
758  inline bool create(char *name, T *pointer)
759  {return keyassoc::create(name, pointer);};
760 
766  inline void remove(char *name)
767  {keyassoc::remove(name);};
768 
774  inline unsigned utilization(void)
775  {return mempager::utilization();};
776 
783  inline unsigned getPages(void)
784  {return mempager::getPages();};
785 };
786 
793 template <typename T>
794 class pager : private MemoryRedirect, private PagerPool
795 {
796 public:
801  inline pager(mempager *heap = NULL) : MemoryRedirect(heap), PagerPool() {};
802 
806  inline ~pager()
807  {mempager::purge();};
808 
813  inline T *operator()(void)
814  {return new(get(sizeof(T))) T;};
815 
820  inline T *operator*()
821  {return new(get(sizeof(T))) T;};
822 };
823 
829 template <class T, unsigned M = 177>
830 class keypager : public mempager
831 {
832 private:
833  NamedObject *idx[M];
834 
835 public:
840  inline keypager(size_t size) : mempager(size) {};
841 
845  inline ~keypager()
846  {NamedObject::purge(idx, M); mempager::purge();};
847 
854  inline T *get(const char *name) const {
855  T *node = (static_cast<T*>(NamedObject::map(idx, name, M)));
856  if(!node) {
857  node = init<T>(static_cast<T*>(mempager::_alloc(sizeof(T))));
858  node->NamedObject::add(idx, name, M);
859  }
860  return node;
861  }
862 
868  bool test(const char *name) const
869  {return NamedObject::map(idx, name, M) != NULL;};
870 
877  inline T *operator[](const char *name) const
878  {return get(name);};
879 
884  inline T *begin(void) const
885  {return static_cast<T*>(NamedObject::skip(idx, NULL, M));};
886 
892  inline T *next(T *current) const
893  {return static_cast<T*>(NamedObject::skip(idx, current, M));};
894 
899  inline unsigned count(void) const
900  {return NamedObject::count(idx, M);};
901 
908  inline T **index(void) const
909  {return NamedObject::index(idx, M);};
910 
917  inline T **sort(void) const
918  {return NamedObject::sort(NamedObject::index(idx, M));};
919 };
920 
925 
930 
935 
936 
937 END_NAMESPACE
938 
939 #endif