00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00030 #ifndef _UCOMMON_MEMORY_H_
00031 #define _UCOMMON_MEMORY_H_
00032
00033 #ifndef _UCOMMON_CONFIG_H_
00034 #include <ucommon/platform.h>
00035 #endif
00036
00037 #ifndef _UCOMMON_PROTOCOLS_H_
00038 #include <ucommon/protocols.h>
00039 #endif
00040
00041 #ifndef _UCOMMON_LINKED_H_
00042 #include <ucommon/linked.h>
00043 #endif
00044
00045 #ifndef _UCOMMON_STRING_H_
00046 #include <ucommon/string.h>
00047 #endif
00048
00049 NAMESPACE_UCOMMON
00050
00051 class PagerPool;
00052
00060 class __EXPORT memalloc : public MemoryProtocol
00061 {
00062 private:
00063 friend class bufpager;
00064
00065 size_t pagesize, align;
00066 unsigned count;
00067
00068 typedef struct mempage {
00069 struct mempage *next;
00070 union {
00071 void *memalign;
00072 unsigned used;
00073 };
00074 } page_t;
00075
00076 page_t *page;
00077
00078 protected:
00079 unsigned limit;
00080
00085 page_t *pager(void);
00086
00090 virtual void fault(void) const;
00091
00092 public:
00097 memalloc(size_t page = 0);
00098
00102 virtual ~memalloc();
00103
00108 inline unsigned pages(void) const
00109 {return count;}
00110
00118 inline unsigned max(void) const
00119 {return limit;}
00120
00125 inline unsigned size(void) const
00126 {return pagesize;}
00127
00138 unsigned utilization(void) const;
00139
00143 void purge(void);
00144
00152 virtual void *_alloc(size_t size);
00153 };
00154
00175 class __EXPORT mempager : public memalloc, public LockingProtocol
00176 {
00177 private:
00178 pthread_mutex_t mutex;
00179
00180 protected:
00187 virtual void _lock(void);
00188
00192 virtual void _unlock(void);
00193
00194 public:
00199 mempager(size_t page = 0);
00200
00204 virtual ~mempager();
00205
00216 unsigned utilization(void);
00217
00221 void purge(void);
00222
00230 virtual void dealloc(void *memory);
00231
00240 virtual void *_alloc(size_t size);
00241 };
00242
00243 class __EXPORT ObjectPager : protected memalloc
00244 {
00245 public:
00246 class __EXPORT member : public LinkedObject
00247 {
00248 private:
00249 void *mem;
00250
00251 protected:
00252 friend class ObjectPager;
00253
00254 inline void set(member *node)
00255 {Next = node;};
00256
00257 inline void *get(void) const
00258 {return mem;};
00259
00260 member(LinkedObject **root);
00261 member();
00262
00263 public:
00264 inline void *operator*() const
00265 {return mem;};
00266 };
00267
00268 private:
00269 unsigned members;
00270 LinkedObject *root;
00271 size_t typesize;
00272 member *last;
00273 void **index;
00274
00275 protected:
00276 ObjectPager(size_t objsize, size_t pagesize = 256);
00277
00284 void *get(unsigned item) const;
00285
00290 void *add(void);
00291
00292 void *push(void);
00293
00298 void *pull(void);
00299
00304 void *pop(void);
00305
00310 void *invalid(void) const;
00311
00312 public:
00317 void clear(void);
00318
00324 inline ObjectPager::member *begin(void)
00325 {return static_cast<ObjectPager::member *>(root);};
00326
00327 inline operator bool() const
00328 {return members > 0;}
00329
00330 inline bool operator!() const
00331 {return !members;}
00332
00337 inline unsigned count(void) const
00338 {return members;};
00339
00343 typedef linked_pointer<ObjectPager::member> iterator;
00344
00345 inline size_t size(void)
00346 {return memalloc::size();}
00347
00348 inline unsigned pages(void)
00349 {return memalloc::pages();}
00350
00351 protected:
00356 void **list(void);
00357 };
00358
00364 class __EXPORT StringPager : protected memalloc
00365 {
00366 private:
00367 unsigned members;
00368 LinkedObject *root;
00369
00370 protected:
00371 virtual const char *invalid(void) const;
00372
00373 public:
00381 virtual bool filter(char *text, size_t size);
00382
00389 class __EXPORT member : public LinkedObject
00390 {
00391 private:
00392 const char *text;
00393
00394 protected:
00395 friend class StringPager;
00396
00397 inline void set(member *node)
00398 {Next = node;};
00399
00400 member(LinkedObject **root, const char *data);
00401 member(const char *data);
00402
00403 public:
00404 inline const char *operator*() const
00405 {return text;};
00406
00407 inline const char *get(void) const
00408 {return text;};
00409 };
00410
00415 StringPager(size_t pagesize = 256);
00416
00417 StringPager(char **list, size_t pagesize = 256);
00418
00423 inline unsigned count(void) const
00424 {return members;};
00425
00432 const char *get(unsigned item) const;
00433
00439 void set(unsigned item, const char *string);
00440
00445 void add(const char *text);
00446
00451 void push(const char *text);
00452
00457 void push(char **text);
00458
00463 const char *pull(void);
00464
00469 const char *pop(void);
00470
00476 void add(char **list);
00477
00483 void set(char **list);
00484
00489 void clear(void);
00490
00497 inline const char *operator[](unsigned item) const
00498 {return get(item);};
00499
00500 inline const char *at(unsigned item) const
00501 {return get(item);};
00502
00508 inline StringPager::member *begin(void) const
00509 {return static_cast<StringPager::member *>(root);};
00510
00515 inline void operator+=(const char *text)
00516 {add(text);};
00517
00522 inline StringPager& operator<<(const char *text)
00523 {add(text); return *this;}
00524
00525 inline StringPager& operator>>(const char *text)
00526 {push(text); return *this;}
00527
00531 void sort(void);
00532
00537 char **list(void);
00538
00547 unsigned token(const char *text, const char *list, const char *quote = NULL, const char *end = NULL);
00548
00549 unsigned split(const char *text, const char *string, unsigned flags = 0);
00550
00551 unsigned split(stringex_t& expr, const char *string, unsigned flags = 0);
00552
00553 String join(const char *prefix = NULL, const char *middle = NULL, const char *suffix = NULL);
00554
00555 inline operator bool()
00556 {return members > 0;}
00557
00558 inline bool operator!()
00559 {return !members;}
00560
00561 inline StringPager& operator=(char **list)
00562 {set(list); return *this;}
00563
00564 inline const char *operator*()
00565 {return pull();}
00566
00567 inline operator char **()
00568 {return list();};
00569
00573 typedef linked_pointer<StringPager::member> iterator;
00574
00575 inline size_t size(void)
00576 {return memalloc::size();}
00577
00578 inline unsigned pages(void)
00579 {return memalloc::pages();}
00580
00581 private:
00582 member *last;
00583 char **index;
00584 };
00585
00593 class __EXPORT DirPager : protected StringPager
00594 {
00595 protected:
00596 const char *dir;
00597
00605 virtual bool filter(char *filename, size_t size);
00606
00612 bool load(const char *path);
00613
00614 public:
00615 DirPager();
00616
00617 DirPager(const char *path);
00618
00619 void operator=(const char *path);
00620
00621 inline const char *operator*() const
00622 {return dir;};
00623
00624 inline operator bool() const
00625 {return dir != NULL;};
00626
00627 inline bool operator!() const
00628 {return dir == NULL;};
00629
00630 inline unsigned count(void) const
00631 {return StringPager::count();};
00632
00639 inline const char *operator[](unsigned item) const
00640 {return StringPager::get(item);};
00641
00642 inline const char *get(unsigned item) const
00643 {return StringPager::get(item);};
00644
00645 inline const char *at(unsigned item) const
00646 {return StringPager::get(item);};
00647
00648 inline size_t size(void)
00649 {return memalloc::size();}
00650
00651 inline unsigned pages(void)
00652 {return memalloc::pages();}
00653 };
00654
00659 class __EXPORT bufpager : public memalloc, public CharacterProtocol
00660 {
00661 private:
00662 typedef struct cpage {
00663 struct cpage *next;
00664 char *text;
00665 unsigned size, used;
00666 } cpage_t;
00667
00668 cpage_t *first, *last, *current, *freelist;
00669 unsigned cpos;
00670 unsigned long ccount;
00671 bool eom;
00672
00673 virtual int _getch(void);
00674 virtual int _putch(int code);
00675
00676 protected:
00677 virtual void *_alloc(size_t size);
00678
00679 public:
00683 void reset(void);
00684
00688 void rewind(void);
00689
00694 char *dup(void);
00695
00700 void set(const char *text);
00701
00706 void add(const char *text);
00707
00714 size_t get(char *text, size_t size);
00715
00721 void put(const char *text, size_t size);
00722
00727 inline unsigned long used(void) const
00728 {return ccount;}
00729
00734 inline char *operator *()
00735 {return dup();}
00736
00741 inline bufpager& operator<<(const char *text)
00742 {add(text); return *this;};
00743
00744 bufpager(size_t page = 0);
00745
00751 char *request(size_t *iosize);
00752
00759 char *copy(size_t *iosize);
00760
00765 void update(size_t size);
00766
00771 inline bool operator!()
00772 {return eom;}
00773
00778 inline operator bool()
00779 {return !eom;}
00780 };
00781
00789 class __EXPORT autorelease
00790 {
00791 private:
00792 LinkedObject *pool;
00793
00794 public:
00798 autorelease();
00799
00803 ~autorelease();
00804
00810 void release(void);
00811
00816 void operator+=(LinkedObject *object);
00817 };
00818
00829 class __EXPORT PagerObject : public LinkedObject, public CountedObject
00830 {
00831 protected:
00832 friend class PagerPool;
00833
00834 PagerPool *pager;
00835
00839 PagerObject();
00840
00844 void reset(void);
00845
00849 void release(void);
00850
00854 void dealloc(void);
00855 };
00856
00865 class __EXPORT PagerPool : public MemoryProtocol
00866 {
00867 private:
00868 LinkedObject *freelist;
00869 pthread_mutex_t mutex;
00870
00871 protected:
00872 PagerPool();
00873 virtual ~PagerPool();
00874
00875 PagerObject *get(size_t size);
00876
00877 public:
00882 void put(PagerObject *object);
00883 };
00884
00885 class __EXPORT charmem : public CharacterProtocol
00886 {
00887 protected:
00888 char *buffer;
00889 size_t inp, out, size;
00890 bool dynamic;
00891
00892 int _getch(void);
00893 int _putch(int code);
00894
00895 public:
00896 charmem(char *mem, size_t size);
00897 charmem(size_t size);
00898 charmem();
00899 virtual ~charmem();
00900
00901 void release(void);
00902
00903 void set(char *mem, size_t size);
00904
00905 void set(size_t size);
00906
00907 inline void reset(void)
00908 {inp = out = 0;}
00909
00910 inline void rewind(void)
00911 {inp = 0;}
00912 };
00913
00914 class __EXPORT chartext : public CharacterProtocol
00915 {
00916 private:
00917 char *pos;
00918 size_t max;
00919
00920 int _putch(int code);
00921 int _getch(void);
00922
00923 public:
00924 chartext();
00925 chartext(char *buf);
00926 chartext(char *buf, size_t size);
00927 virtual ~chartext();
00928 };
00929
00941 class __EXPORT keyassoc : protected mempager
00942 {
00943 private:
00947 class __LOCAL keydata : public NamedObject
00948 {
00949 public:
00950 void *data;
00951 char text[8];
00952
00953 keydata(keyassoc *assoc, const char *id, unsigned max, unsigned bufsize);
00954 };
00955
00956 friend class keydata;
00957
00958 unsigned keycount;
00959 unsigned paths;
00960 size_t keysize;
00961 NamedObject **root;
00962 LinkedObject **list;
00963
00964 protected:
00971 void *allocate(const char *name, size_t size);
00972
00973 public:
00980 keyassoc(unsigned indexing = 177, size_t max = 0, size_t page = 0);
00981
00985 ~keyassoc();
00986
00991 inline unsigned count(void) const
00992 {return keycount;};
00993
00999 inline void *operator()(const char *name)
01000 {return locate(name);};
01001
01005 void purge(void);
01006
01012 void *locate(const char *name);
01013
01021 bool assign(const char *name, void *pointer);
01022
01029 bool create(const char *name, void *pointer);
01030
01037 void *remove(const char *name);
01038 };
01039
01040 template <class T, size_t P = 0>
01041 class listof : private ObjectPager
01042 {
01043 public:
01044 inline listof() : ObjectPager(sizeof(T), P) {};
01045
01046 inline T& operator[](unsigned item) const
01047 {return (T&)ObjectPager::get(item);}
01048
01049 inline T* operator()(unsigned item) const
01050 {return (T*)ObjectPager::get(item);}
01051
01052 inline const T& at(unsigned item) const
01053 {return (const T&)ObjectPager::get(item);}
01054
01055 inline T* pull(void)
01056 {return (T*)ObjectPager::pull();}
01057
01058 inline T* pop(void)
01059 {return (T*)ObjectPager::pop();}
01060
01061 inline operator T**()
01062 {return (T**)ObjectPager::list();}
01063
01064 inline T** list(void)
01065 {return (T**)ObjectPager::list();}
01066
01067 inline T* operator++(void)
01068 {T* tmp = ObjectPager::add(); if(tmp) new((caddr_t)tmp) T; return tmp;}
01069
01070 inline T* add(const T& object)
01071 {T* tmp = ObjectPager::add(); if(tmp) new((caddr_t)tmp) T(object); return tmp;}
01072
01073 inline T* push(const T& object)
01074 {T* tmp = ObjectPager::push(); if(tmp) new((caddr_t)tmp) T(object); return tmp;}
01075
01076 inline listof& operator<<(const T& object)
01077 {T* tmp = ObjectPager::add(); if(tmp) new((caddr_t)tmp) T(object); return *this;}
01078
01079 inline listof& operator>>(const T& object)
01080 {T* tmp = ObjectPager::push(); if(tmp) new((caddr_t)tmp) T(object); return *this;}
01081
01082 };
01083
01084 template <class T, unsigned I = 177, size_t M = 0, size_t P = 0>
01085 class mapof : private keyassoc
01086 {
01087 public:
01091 inline mapof() : keyassoc(I, M, P) {};
01092
01097 inline unsigned count(void) const
01098 {return keyassoc::count();};
01099
01103 inline void purge(void)
01104 {keyassoc::purge();};
01105
01111 inline T *locate(const char *name)
01112 {return static_cast<T*>(keyassoc::locate(name));}
01113
01114 inline T *operator[](const char *name)
01115 {return static_cast<T*>(keyassoc::locate(name));}
01116
01122 inline T *operator()(const char *name)
01123 {return locate(name);};
01124
01129 inline T *map(const char *name)
01130 {T *tmp = keyassoc::allocate(name, sizeof(T)); if(tmp) new((caddr_t)tmp) T;}
01131
01137 inline void unmap(const char *name)
01138 {keyassoc::remove(name);};
01139
01145 inline unsigned utilization(void)
01146 {return mempager::utilization();};
01147
01154 inline unsigned pages(void) const
01155 {return mempager::pages();};
01156 };
01157
01165 template <class T, unsigned I = 177, size_t M = 0, size_t P = 0>
01166 class assoc_pointer : private keyassoc
01167 {
01168 public:
01172 inline assoc_pointer() : keyassoc(I, M, P) {};
01173
01178 inline unsigned count(void) const
01179 {return keyassoc::count();}
01180
01184 inline void purge(void)
01185 {keyassoc::purge();}
01186
01192 inline T *locate(const char *name)
01193 {return static_cast<T*>(keyassoc::locate(name));}
01194
01195 inline T *operator[](const char *name)
01196 {return static_cast<T*>(keyassoc::locate(name));}
01197
01198
01204 inline T *operator()(const char *name)
01205 {return locate(name);}
01206
01214 inline bool assign(char *name, T *pointer)
01215 {return keyassoc::assign(name, pointer);}
01216
01223 inline bool create(char *name, T *pointer)
01224 {return keyassoc::create(name, pointer);}
01225
01231 inline void remove(char *name)
01232 {keyassoc::remove(name);}
01233
01239 inline unsigned utilization(void) const
01240 {return mempager::utilization();}
01241
01248 inline unsigned pages(void) const
01249 {return mempager::pages();}
01250 };
01251
01258 template <typename T>
01259 class pager : private MemoryRedirect, private PagerPool
01260 {
01261 public:
01266 inline pager(mempager *heap = NULL) : MemoryRedirect(heap), PagerPool() {};
01267
01272 inline T *operator()(void)
01273 {return new(get(sizeof(T))) T;};
01274
01279 inline T *operator*()
01280 {return new(get(sizeof(T))) T;};
01281 };
01282
01288 template <class T, unsigned M = 177>
01289 class keypager : public mempager
01290 {
01291 private:
01292 NamedObject *idx[M];
01293
01294 public:
01299 inline keypager(size_t size) : mempager(size) {};
01300
01304 inline ~keypager()
01305 {NamedObject::purge(idx, M); mempager::purge();};
01306
01313 inline T *get(const char *name) const {
01314 T *node = (static_cast<T*>(NamedObject::map(idx, name, M)));
01315 if(!node) {
01316 node = init<T>(static_cast<T*>(mempager::_alloc(sizeof(T))));
01317 node->NamedObject::add(idx, name, M);
01318 }
01319 return node;
01320 }
01321
01327 bool test(const char *name) const
01328 {return NamedObject::map(idx, name, M) != NULL;};
01329
01336 inline T *operator[](const char *name) const
01337 {return get(name);};
01338
01343 inline T *begin(void) const
01344 {return static_cast<T*>(NamedObject::skip(idx, NULL, M));};
01345
01351 inline T *next(T *current) const
01352 {return static_cast<T*>(NamedObject::skip(idx, current, M));};
01353
01358 inline unsigned count(void) const
01359 {return NamedObject::count(idx, M);};
01360
01367 inline T **index(void) const
01368 {return NamedObject::index(idx, M);};
01369
01376 inline T **sort(void) const
01377 {return NamedObject::sort(NamedObject::index(idx, M));};
01378
01382 typedef linked_pointer<T> iterator;
01383 };
01384
01388 typedef StringPager stringlist_t;
01389
01393 typedef StringPager::member stringlistitem_t;
01394
01398 typedef DirPager dirlist_t;
01399
01400 inline const char *shift(stringlist_t& list)
01401 {return list.pull();}
01402
01403 inline void unshift(stringlist_t& list, const char *text)
01404 {list.push(text);}
01405
01406
01407 inline String str(StringPager& list, const char *prefix = NULL, const char *middle = NULL, const char *suffix = NULL)
01408 {return list.join(prefix, middle, suffix);}
01409
01410 END_NAMESPACE
01411
01412 #endif