00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef VERTEXDATAPAGE_H
00016 #define VERTEXDATAPAGE_H
00017
00018 #include "pandabase.h"
00019 #include "simpleLru.h"
00020 #include "simpleAllocator.h"
00021 #include "pStatCollector.h"
00022 #include "vertexDataSaveFile.h"
00023 #include "pmutex.h"
00024 #include "conditionVar.h"
00025 #include "conditionVarFull.h"
00026 #include "thread.h"
00027 #include "mutexHolder.h"
00028 #include "pdeque.h"
00029
00030 class VertexDataBook;
00031 class VertexDataBlock;
00032
00033
00034
00035
00036
00037
00038
00039
00040 class EXPCL_PANDA_GOBJ VertexDataPage : public SimpleAllocator, public SimpleLruPage {
00041 private:
00042 VertexDataPage(size_t book_size);
00043 VertexDataPage(VertexDataBook *book, size_t page_size, size_t block_size);
00044 virtual ~VertexDataPage();
00045
00046 PUBLISHED:
00047
00048
00049
00050 enum RamClass {
00051 RC_resident,
00052 RC_compressed,
00053 RC_disk,
00054
00055 RC_end_of_list,
00056 };
00057
00058 INLINE RamClass get_ram_class() const;
00059 INLINE RamClass get_pending_ram_class() const;
00060 INLINE void request_resident();
00061
00062 INLINE VertexDataBlock *alloc(size_t size);
00063 INLINE VertexDataBlock *get_first_block() const;
00064
00065 INLINE VertexDataBook *get_book() const;
00066
00067 INLINE static SimpleLru *get_global_lru(RamClass rclass);
00068 INLINE static SimpleLru *get_pending_lru();
00069 INLINE static VertexDataSaveFile *get_save_file();
00070
00071 INLINE bool save_to_disk();
00072
00073 INLINE static int get_num_threads();
00074 INLINE static int get_num_pending_reads();
00075 INLINE static int get_num_pending_writes();
00076 static void stop_threads();
00077 static void flush_threads();
00078
00079 virtual void output(ostream &out) const;
00080 virtual void write(ostream &out, int indent_level) const;
00081
00082 public:
00083 INLINE unsigned char *get_page_data(bool force);
00084 INLINE bool operator < (const VertexDataPage &other) const;
00085
00086 protected:
00087 virtual SimpleAllocatorBlock *make_block(size_t start, size_t size);
00088 virtual void changed_contiguous();
00089 virtual void evict_lru();
00090
00091 private:
00092 class PageThread;
00093
00094 VertexDataBlock *do_alloc(size_t size);
00095
00096 void make_resident_now();
00097 void make_resident();
00098 void make_compressed();
00099 void make_disk();
00100
00101 bool do_save_to_disk();
00102 void do_restore_from_disk();
00103
00104 void adjust_book_size();
00105
00106 void request_ram_class(RamClass ram_class);
00107 INLINE void set_ram_class(RamClass ram_class);
00108 static void make_save_file();
00109
00110 INLINE size_t round_up(size_t page_size) const;
00111 unsigned char *alloc_page_data(size_t page_size) const;
00112 void free_page_data(unsigned char *page_data, size_t page_size) const;
00113
00114 typedef pdeque<VertexDataPage *> PendingPages;
00115
00116 class PageThreadManager;
00117 class PageThread : public Thread {
00118 public:
00119 PageThread(PageThreadManager *manager, const string &name);
00120
00121 protected:
00122 virtual void thread_main();
00123
00124 private:
00125 PageThreadManager *_manager;
00126 VertexDataPage *_working_page;
00127
00128
00129
00130 ConditionVar _working_cvar;
00131 friend class PageThreadManager;
00132 };
00133 typedef pvector<PT(PageThread) > PageThreads;
00134
00135 class PageThreadManager : public ReferenceCount {
00136 public:
00137 PageThreadManager(int num_threads);
00138 void add_page(VertexDataPage *page, RamClass ram_class);
00139 void remove_page(VertexDataPage *page);
00140 int get_num_threads() const;
00141 int get_num_pending_reads() const;
00142 int get_num_pending_writes() const;
00143 void start_threads(int num_threads);
00144 void stop_threads();
00145
00146 private:
00147 PendingPages _pending_writes;
00148 PendingPages _pending_reads;
00149 bool _shutdown;
00150
00151
00152
00153
00154 ConditionVarFull _pending_cvar;
00155
00156 PageThreads _threads;
00157 friend class PageThread;
00158 };
00159
00160 static PT(PageThreadManager) _thread_mgr;
00161 static Mutex &_tlock;
00162
00163 unsigned char *_page_data;
00164 size_t _size, _allocated_size, _uncompressed_size;
00165 RamClass _ram_class;
00166 PT(VertexDataSaveBlock) _saved_block;
00167 size_t _book_size;
00168 size_t _block_size;
00169
00170
00171 RamClass _pending_ram_class;
00172
00173 VertexDataBook *_book;
00174
00175 enum { deflate_page_size = 1024, inflate_page_size = 1024 };
00176
00177
00178
00179 class DeflatePage {
00180 public:
00181 DeflatePage() {
00182 _used_size = 0;
00183 _next = NULL;
00184 }
00185 ALLOC_DELETED_CHAIN(DeflatePage);
00186
00187 unsigned char _buffer[deflate_page_size];
00188 size_t _used_size;
00189 DeflatePage *_next;
00190
00191 public:
00192 static TypeHandle get_class_type() {
00193 return _type_handle;
00194 }
00195 static void init_type() {
00196 register_type(_type_handle, "VertexDataPage::DeflatePage");
00197 }
00198
00199 private:
00200 static TypeHandle _type_handle;
00201 };
00202
00203 static SimpleLru _resident_lru;
00204 static SimpleLru _compressed_lru;
00205 static SimpleLru _disk_lru;
00206 static SimpleLru _pending_lru;
00207 static SimpleLru *_global_lru[RC_end_of_list];
00208
00209 static VertexDataSaveFile *_save_file;
00210
00211 static Mutex _unused_mutex;
00212
00213 static PStatCollector _vdata_compress_pcollector;
00214 static PStatCollector _vdata_decompress_pcollector;
00215 static PStatCollector _vdata_save_pcollector;
00216 static PStatCollector _vdata_restore_pcollector;
00217 static PStatCollector _thread_wait_pcollector;
00218 static PStatCollector _alloc_pages_pcollector;
00219
00220 public:
00221 static TypeHandle get_class_type() {
00222 return _type_handle;
00223 }
00224 static void init_type() {
00225 register_type(_type_handle, "VertexDataPage");
00226 }
00227
00228 private:
00229 static TypeHandle _type_handle;
00230
00231 friend class PageThread;
00232 friend class VertexDataBook;
00233 };
00234
00235 inline ostream &operator << (ostream &out, const VertexDataPage &page) {
00236 page.output(out);
00237 return out;
00238 }
00239
00240 #include "vertexDataPage.I"
00241
00242 #endif