Panda3D
 All Classes Functions Variables Enumerations
vertexDataBook.cxx
00001 // Filename: vertexDataBook.cxx
00002 // Created by:  drose (16May07)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "vertexDataBook.h"
00016 #include "mutexHolder.h"
00017 
00018 ////////////////////////////////////////////////////////////////////
00019 //     Function: VertexDataBook::Constructor
00020 //       Access: Published
00021 //  Description: 
00022 ////////////////////////////////////////////////////////////////////
00023 VertexDataBook::
00024 VertexDataBook(size_t block_size) {
00025   // Make sure the block_size is an integer multiple of the system's
00026   // page size.
00027   _block_size = memory_hook->round_up_to_page_size(block_size);
00028 }
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: VertexDataBook::Destructor
00032 //       Access: Published
00033 //  Description: 
00034 ////////////////////////////////////////////////////////////////////
00035 VertexDataBook::
00036 ~VertexDataBook() {
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: VertexDataBook::count_total_page_size
00041 //       Access: Published
00042 //  Description: Returns the total size of all bytes owned by all
00043 //               pages owned by this book.
00044 ////////////////////////////////////////////////////////////////////
00045 size_t VertexDataBook::
00046 count_total_page_size() const {
00047   MutexHolder holder(_lock);
00048 
00049   size_t total = 0;
00050   Pages::const_iterator pi;
00051   for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
00052     total += (*pi)->get_max_size();
00053   }
00054   return total;
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: VertexDataBook::count_total_page_size
00059 //       Access: Published
00060 //  Description: Returns the total size of all bytes owned by all
00061 //               pages owned by this book that have the indicated ram
00062 //               class.
00063 ////////////////////////////////////////////////////////////////////
00064 size_t VertexDataBook::
00065 count_total_page_size(VertexDataPage::RamClass ram_class) const {
00066   MutexHolder holder(_lock);
00067 
00068   size_t total = 0;
00069   Pages::const_iterator pi;
00070   for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
00071     if ((*pi)->get_ram_class() == ram_class) {
00072       total += (*pi)->get_max_size();
00073     }
00074   }
00075   return total;
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: VertexDataBook::count_allocated_size
00080 //       Access: Published
00081 //  Description: Returns the total size of all bytes allocated within
00082 //               pages owned by this book.
00083 ////////////////////////////////////////////////////////////////////
00084 size_t VertexDataBook::
00085 count_allocated_size() const {
00086   MutexHolder holder(_lock);
00087 
00088   size_t total = 0;
00089   Pages::const_iterator pi;
00090   for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
00091     total += (*pi)->get_total_size();
00092   }
00093   return total;
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: VertexDataBook::count_allocated_size
00098 //       Access: Published
00099 //  Description: Returns the total size of all bytes allocated within
00100 //               pages owned by this book that have the indicated ram
00101 //               class.
00102 ////////////////////////////////////////////////////////////////////
00103 size_t VertexDataBook::
00104 count_allocated_size(VertexDataPage::RamClass ram_class) const {
00105   MutexHolder holder(_lock);
00106 
00107   size_t total = 0;
00108   Pages::const_iterator pi;
00109   for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
00110     if ((*pi)->get_ram_class() == ram_class) {
00111       total += (*pi)->get_total_size();
00112     }
00113   }
00114   return total;
00115 }
00116 
00117 ////////////////////////////////////////////////////////////////////
00118 //     Function: VertexDataBook::save_to_disk
00119 //       Access: Published
00120 //  Description: Writes all pages to disk immediately, just in case
00121 //               they get evicted later.  It makes sense to make this
00122 //               call just before taking down a loading screen, to
00123 //               minimize chugs from saving pages inadvertently later.
00124 ////////////////////////////////////////////////////////////////////
00125 void VertexDataBook::
00126 save_to_disk() {
00127   MutexHolder holder(_lock);
00128 
00129   Pages::iterator pi;
00130   for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
00131     (*pi)->save_to_disk();
00132   }
00133 }
00134 
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: VertexDataBook::do_alloc
00138 //       Access: Private
00139 //  Description: Allocates and returns a new VertexDataBuffer of the
00140 //               requested size.
00141 //
00142 //               Assumes the lock is already held.
00143 ////////////////////////////////////////////////////////////////////
00144 VertexDataBlock *VertexDataBook::
00145 do_alloc(size_t size) {
00146   // Look for an empty page of the appropriate size.  The _pages set
00147   // is sorted so that the pages with the smallest available blocks
00148   // are at the front.
00149   
00150   // Create a dummy page to use to search the set.
00151   VertexDataPage size_page(size);
00152   Pages::iterator pi = _pages.lower_bound(&size_page);
00153 
00154   // Now we can start from the first element of the set that is
00155   // possibly large enough to contain this block, and work up from
00156   // there.
00157   while (pi != _pages.end()) {
00158     Pages::iterator pnext = pi;
00159     ++pnext;
00160 
00161     VertexDataPage *page = (*pi);
00162 
00163     // Allocating a block may change the page's available contiguous
00164     // size, and thereby change its position in the set, invalidating
00165     // the iterator pi.  This is why we've already computed pnext.
00166     VertexDataBlock *block = page->do_alloc(size);
00167 
00168     if (block != (VertexDataBlock *)NULL) {
00169       // This page worked.
00170       return block;
00171     }
00172 
00173     // Try the next page.
00174     pi = pnext;
00175   }
00176 
00177   // No page was good enough.  Create a new page.  Make it at least
00178   // large enough to hold this requested block.
00179   VertexDataPage *page = create_new_page(size);
00180   _pages.insert(page);
00181 
00182   VertexDataBlock *block = page->do_alloc(size);
00183   return block;
00184 }
 All Classes Functions Variables Enumerations