gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/rtmp r9729: add the cache and gather stati


From: rob
Subject: [Gnash-commit] /srv/bzr/gnash/rtmp r9729: add the cache and gather statistics.
Date: Fri, 14 Nov 2008 20:17:57 -0700
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 9729
committer: address@hidden
branch nick: rtmp
timestamp: Fri 2008-11-14 20:17:57 -0700
message:
  add the cache and gather statistics.
modified:
  libnet/cache.cpp
  libnet/cache.h
  libnet/diskstream.cpp
  libnet/diskstream.h
  libnet/http.cpp
=== modified file 'libnet/cache.cpp'
--- a/libnet/cache.cpp  2008-11-13 04:46:27 +0000
+++ b/libnet/cache.cpp  2008-11-15 03:17:57 +0000
@@ -44,13 +44,111 @@
 {
 
 Cache::Cache() 
-    : _max_size(0)
+    : _max_size(0),
+#ifdef USE_STATS_CACHE
+      _pathname_lookups(0),
+      _pathname_hits(0),
+      _response_lookups(0),
+      _response_hits(0),
+      _file_lookups(0),
+      _file_hits(0),
+#endif
+      _pagesize(0)
 {
+//    GNASH_REPORT_FUNCTION;
+    log_error("using this constructor is only allowed for testing purposes.");
+#ifdef USE_STATS_CACHE
+    clock_gettime (CLOCK_REALTIME, &_last_access);
+#endif
 }
 
 Cache::~Cache()
 {
-}
+//    GNASH_REPORT_FUNCTION;
+}
+
+Cache&
+Cache::getDefaultInstance()
+{
+//    GNASH_REPORT_FUNCTION;
+    static Cache c;
+    return c;
+}
+
+void
+Cache::addPath(const std::string &name, const std::string &fullpath)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::mutex::scoped_lock lock(cache_mutex);
+    _pathnames[name] = fullpath;
+};
+
+void
+Cache::addResponse(const std::string &name, const std::string &response)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::mutex::scoped_lock lock(cache_mutex);
+    _responses[name] = response;
+};
+
+void
+Cache::addFile(const std::string &name, DiskStream *file)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::mutex::scoped_lock lock(cache_mutex);
+    _files[name] = file;
+};
+
+string &
+Cache::findPath(const std::string &name)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::mutex::scoped_lock lock(cache_mutex);
+#ifdef USE_STATS_CACHE
+    clock_gettime (CLOCK_REALTIME, &_last_access);
+    _pathname_lookups++;
+    map<string, string>::iterator it;
+    it = _pathnames.find(name);
+    if (it != _pathnames.end()) {
+        _pathname_hits++;
+    }
+#endif
+    return _pathnames[name];
+};
+
+string &
+Cache::findResponse(const std::string &name)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::mutex::scoped_lock lock(cache_mutex);
+#ifdef USE_STATS_CACHE
+    clock_gettime (CLOCK_REALTIME, &_last_access);
+    _response_lookups++;
+    map<string, string>::const_iterator it;
+    it = _responses.find(name);
+    if (it != _responses.end()) {
+        _response_hits++;
+    }
+#endif
+    return _responses[name];
+};
+
+DiskStream *
+Cache::findFile(const std::string &name)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::mutex::scoped_lock lock(cache_mutex);
+#ifdef USE_STATS_CACHE
+    clock_gettime (CLOCK_REALTIME, &_last_access);
+    _file_lookups++;
+    map<string, DiskStream *>::const_iterator it;
+    it = _files.find(name);
+    if (it != _files.end()) {
+        _file_hits++;
+    }
+#endif
+    return _files[name];
+};
 
 void
 Cache::removePath(const std::string &name)
@@ -76,6 +174,50 @@
     _files.erase(name);
 }
 
+#ifdef USE_STATS_CACHE
+boost::shared_ptr<string>
+Cache::stats() const
+{
+//    GNASH_REPORT_FUNCTION;
+    // dump timing related data
+    struct timespec now;
+    stringstream text;
+    
+    clock_gettime (CLOCK_REALTIME, &now);    
+    double time = ((now.tv_sec - _last_access.tv_sec) + ((now.tv_nsec - 
_last_access.tv_nsec)/1e9));
+    
+    text << "Time since last access:  " << fixed << ((now.tv_sec - 
_last_access.tv_sec) + ((now.tv_nsec - _last_access.tv_nsec)/1e9)) << " seconds 
ago." << endl;
+
+    text << "Pathnames in cache: " << _pathnames.size() << " accessed "
+        << _pathname_lookups << " times" << endl;
+     text << "Pathname hits from cache: " << _pathname_hits << endl;
+    
+    text << "Responses in cache: " << _responses.size() << " accessed "
+        << _response_lookups << " times" << endl;
+    text << "Response hits from cache: " << _response_hits << endl;
+
+    text << "Files in cache: " << _files.size() << " accessed "
+        << _file_lookups << " times" << endl;
+    text << "File hits from cache: " << _file_hits << endl;
+
+#if 0
+    map<std::string, DiskStream *>::const_iterator data;
+    for (data = _files.begin(); data != _files.end(); data++) {
+        const struct timespec *last = data->second->getLastAccessTime();
+       text << "Disktream: " << data->first << endl;
+       time = ((now.tv_sec - last->tv_sec) + ((now.tv_nsec - 
last->tv_nsec)/1e9));
+       text << "Time since last file access:  " << fixed << time << " seconds 
ago." << endl;
+    }
+#endif
+
+    cerr << text.str() << endl;
+    
+    boost::shared_ptr<string> str;
+
+    return str;
+}
+#endif
+
 void
 Cache::dump(std::ostream& os) const
 {    
@@ -83,7 +225,7 @@
     boost::mutex::scoped_lock lock(cache_mutex);
 
     // Dump all the pathnames
-    map<std::string, std::string>::const_iterator name;
+    map<string, string>::const_iterator name;
     for (name = _pathnames.begin(); name != _pathnames.end(); name++) {
         os << "Full path for \"" << name->first << "\" is: " << name->second 
<< endl;
     }
@@ -101,6 +243,10 @@
 //        filedata.dump(os) << endl;
     }
 #endif
+
+#ifdef USE_STATS_CACHE
+    this->stats();
+#endif
 }
 
 } // end of gnash namespace

=== modified file 'libnet/cache.h'
--- a/libnet/cache.h    2008-11-13 02:08:11 +0000
+++ b/libnet/cache.h    2008-11-15 03:17:57 +0000
@@ -19,12 +19,18 @@
 #ifndef __CACHE_H__
 #define __CACHE_H__
 
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
 #include <string>
 #include <map> 
 #include <iostream> // for output operator
+#include <boost/shared_ptr.hpp>
 
 #include "statistics.h"
 #include "diskstream.h"
+#include "getclocktime.hpp"
 
 /// \namespace gnash
 ///    This is the main namespace for Gnash and it's libraries.
@@ -39,34 +45,59 @@
 public:
     Cache();
     ~Cache();
+    static Cache& getDefaultInstance();
     
-    void addPath(const std::string &name, const std::string &fullpath) { 
_pathnames[name] = fullpath; };
-    std::string &findPath(const std::string &name) { return _pathnames[name]; 
};
+    void addPath(const std::string &name, const std::string &fullpath);
+    std::string &findPath(const std::string &name);
     void removePath(const std::string &name);
-
-    void addResponse(const std::string &name, const std::string &response) { 
_responses[name] = response; };
+    
+    void addResponse(const std::string &name, const std::string &response);
+    std::string &findResponse(const std::string &name);
     void removeResponse(const std::string &name);
-
-    std::string &findResponse(const std::string &name) { return 
_responses[name]; };
-
-    void addFile(const std::string &name, DiskStream *file) { _files[name] = 
file; };
-    DiskStream *findFile(const std::string &name) { return _files[name]; };
+    
+    void addFile(const std::string &name, DiskStream *file);
+    DiskStream *findFile(const std::string &name);
     void removeFile(const std::string &name);
-
+    
     ///  \brief Dump the internal data of this class in a human readable form.
     /// @remarks This should only be used for debugging purposes.
     void dump() const { dump(std::cerr); }
     /// \overload dump(std::ostream& os) const
     void dump(std::ostream& os) const;    
-    
+
+#ifdef USE_STATS_CACHE
+    boost::shared_ptr<std::string> stats() const;
+#endif
 private:
+    /// \var Cache::_pathnames
+    ///                The cache of file names converted to absolute path 
names.
     std::map<std::string, std::string> _pathnames;
+    /// \var Cache::
+    ///                The cache of HTTP responses.
     std::map<std::string, std::string> _responses;
+    /// \var Cache::_responses
+    ///                The cache of Distream handles to often played files.
     std::map<std::string, DiskStream *> _files;
+
+    /// \var Cache::_max_size
+    ///                The maximum amount of memory the cache is allowed to 
use.
     size_t _max_size;
+
+    /// \brief Cache file statistics variables are defined here.
+#ifdef USE_STATS_CACHE
+    struct timespec _last_access;
+    long       _pathname_lookups;
+    long       _pathname_hits;
+    long       _response_lookups;
+    long       _response_hits;
+    long       _file_lookups;
+    long       _file_hits;
+#endif
     /// \var Cache::_pagesize
     ///                The memory page size.
-    size_t     pagesize;        
+    size_t     _pagesize;    
+
+amf::AMF::filetype_e  _filetype; // FIXME: this shouldn't be here still
 };
 
 /// \brief Dump to the specified output stream.

=== modified file 'libnet/diskstream.cpp'
--- a/libnet/diskstream.cpp     2008-11-13 01:16:57 +0000
+++ b/libnet/diskstream.cpp     2008-11-15 03:17:57 +0000
@@ -35,6 +35,8 @@
 #include "log.h"
 #include "cque.h"
 #include "diskstream.h"
+#include "cache.h"
+#include "getclocktime.hpp"
 
 #include <boost/thread/mutex.hpp>
 static boost::mutex io_mutex;
@@ -42,14 +44,12 @@
 using namespace gnash;
 using namespace std;
 
-// namespace {
-// gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
-// }
-
 /// \namespace gnash
 ///    This is the main namespace for Gnash and it's libraries.
 namespace gnash {
 
+static Cache& cache = Cache::getDefaultInstance();
+
 /// \def _SC_PAGESIZE
 ///    This isn't set on all systems, but is used to get the page
 ///    size used for memory allocations.
@@ -58,8 +58,7 @@
 #endif
 
 DiskStream::DiskStream()
-    : _bytes(0),
-      _filefd(0),
+    : _filefd(0),
       _netfd(0),
       _dataptr(0),
       _filesize(0),
@@ -67,11 +66,13 @@
       _offset(0)
 {
 //    GNASH_REPORT_FUNCTION;
+#ifdef USE_STATS_CACHE
+    clock_gettime (CLOCK_REALTIME, &_last_access);
+#endif
 }
 
 DiskStream::DiskStream(const string &str)
-    : _bytes(0),
-      _filefd(0),
+    : _filefd(0),
       _netfd(0),
       _dataptr(0),
       _filesize(0),
@@ -80,11 +81,13 @@
 {
 //    GNASH_REPORT_FUNCTION;
     _filespec = str;
+#ifdef USE_STATS_CACHE
+    clock_gettime (CLOCK_REALTIME, &_last_access);
+#endif
 }
 
 DiskStream::DiskStream(const string &str, int netfd)
-    : _bytes(0),
-      _filefd(0),
+    : _filefd(0),
       _filespec(0),
       _dataptr(0),
       _filesize(0),
@@ -94,6 +97,9 @@
 //    GNASH_REPORT_FUNCTION;
     _netfd = netfd;
     _filespec = str;
+#ifdef USE_STATS_CACHE
+    clock_gettime (CLOCK_REALTIME, &_last_access);
+#endif
 }
 
 DiskStream::~DiskStream()
@@ -121,26 +127,6 @@
     _filespec.clear();
 }
 
-///  \brief Dump the internal data of this class in a human readable form.
-/// @remarks This should only be used for debugging purposes.
-void
-DiskStream::dump()
-{
-//    GNASH_REPORT_FUNCTION;
-    //state_e     _state;
-    cerr << "Bytes read is is " << _bytes << endl;
-    cerr << "Disk file descriptor is " << _filefd << endl;
-    cerr << "Network file descritor is " << _netfd << endl;
-    cerr << "Filespec is " << _filespec << endl;
-//    gnash::Statistics  _statistics;
-//     unsigned char *_dataptr;
-//     unsigned char *_seekptr;
-    cerr << "File size is " <<  _filesize << endl;
-    cerr << "Memory Page size is " << _pagesize << endl;
-
-    _que.dump();
-}
-
 /// \brief Load a chunk (pagesize) of the file into memory.
 ///    This loads a pagesize of the disk file into memory. We read
 ///    the file this way as it is faster and takes less resources
@@ -179,23 +165,23 @@
     }
     
     if (_filefd) {
-    /// If the data pointer is legit, then we need to unmap that page
-    /// to mmap() a new one. If we're still in the current mapped
-    /// page, then just return the existing data pointer.
-    if (_dataptr != 0) {
-       // If the offset is less than what we already mmapped, we
-       boost::uint32_t diff = *reinterpret_cast<boost::uint32_t *>(_dataptr + 
_offset);
-       if (diff < _pagesize) {
-           return _dataptr + _offset;
-           // unmap the old data before allocating a new chunk
-       } else {
-           munmap(_dataptr, _pagesize);
-           _dataptr = 0;
+       /// If the data pointer is legit, then we need to unmap that page
+       /// to mmap() a new one. If we're still in the current mapped
+       /// page, then just return the existing data pointer.
+       if (_dataptr != 0) {
+           // If the offset is less than what we already mmapped, we
+           boost::uint32_t diff = *reinterpret_cast<boost::uint32_t 
*>(_dataptr + _offset);
+           if (diff < _pagesize) {
+               return _dataptr + _offset;
+               // unmap the old data before allocating a new chunk
+           } else {
+               munmap(_dataptr, _pagesize);
+               _dataptr = 0;
+           }
        }
-    }
-
+       
        _dataptr = static_cast<unsigned char *>(mmap(0, _pagesize,
-                                       PROT_READ, MAP_SHARED, _filefd, 
_offset));
+                                                    PROT_READ, MAP_SHARED, 
_filefd, _offset));
        offset = (offset % _pagesize);
     } else {
        log_error (_("Couldn't load file %s"), _filespec);
@@ -207,6 +193,7 @@
                   _filespec, strerror(errno));
        return 0;
     } else {
+       clock_gettime (CLOCK_REALTIME, &_last_access);
 //     log_debug (_("File %s mapped to: %p"), _filespec, (void *)_dataptr);
        _seekptr = _dataptr + offset;
        _state = OPEN;
@@ -300,7 +287,11 @@
     } else {
        log_error (_("File %s doesn't exist"), filespec);
     }
-
+    
+#ifdef USE_STATS_CACHE
+    clock_gettime (CLOCK_REALTIME, &_first_access);
+#endif
+    
     /// \brief get the pagesize and cache the value
 #ifdef HAVE_SYSCONF
     _pagesize = sysconf(_SC_PAGESIZE);
@@ -486,11 +477,35 @@
     log_unimpl("%s", __PRETTY_FUNCTION__);
     return true; // Default to true    
 }
+
+///  \brief Dump the internal data of this class in a human readable form.
+/// @remarks This should only be used for debugging purposes.
 void
-DiskStream::dump(std::ostream& os) const
+DiskStream::dump()
 {
+//    GNASH_REPORT_FUNCTION;
+       //state_e     _state;
+    cerr << "Filespec is \"" << _filespec << "\"" << endl;
+       cerr << "Disk file descriptor is fd #" << _filefd << endl;
+       cerr << "Network file descritor is fd #" << _netfd << endl;
+       cerr << "File size is " <<  _filesize << endl;
+       cerr << "Memory Page size is " << _pagesize << endl;
+       cerr << "Memory Offset is " << _offset << endl;
+       
+       // dump timing related data
+       struct timespec now;
+       clock_gettime (CLOCK_REALTIME, &now);    
+       double time = ((now.tv_sec - _last_access.tv_sec) + ((now.tv_nsec - 
_last_access.tv_nsec)/1e9));
+       
+       cerr << "Time since last access:  " << fixed << ((now.tv_sec - 
_last_access.tv_sec) + ((now.tv_nsec - _last_access.tv_nsec)/1e9)) << " seconds 
ago." << endl;
+       
+#ifdef USE_STATS_CACHE
+       cerr << "Time since first access: " << fixed <<
+           ((_last_access.tv_sec - _first_access.tv_sec) + 
((_last_access.tv_nsec - _first_access.tv_nsec)/1e9))
+            << " seconds lifespan."
+            << endl;
+#endif
     
-//    GNASH_REPORT_FUNCTION;
 }
 
 

=== modified file 'libnet/diskstream.h'
--- a/libnet/diskstream.h       2008-11-13 01:16:57 +0000
+++ b/libnet/diskstream.h       2008-11-15 03:17:57 +0000
@@ -26,8 +26,10 @@
 #include <string>
 #include <iostream> 
 
+#include "amf.h"
 #include "cque.h"
 #include "statistics.h"
+#include "getclocktime.hpp"
 
 /// \namespace gnash
 ///    This is the main namespace for Gnash and it's libraries.
@@ -165,7 +167,7 @@
     /// @return nothing.
     void setPagesize(size_t size) { _pagesize = size; };
     
-    ///  \brief Dump the internal data of this class in a human readable form.
+    /// \brief Dump the internal data of this class in a human readable form.
     /// @remarks This should only be used for debugging purposes.
      void dump();
 //    friend std::ostream& operator<< (std::ostream &os, const DiskStream &ds);
@@ -179,18 +181,31 @@
     ///
     /// @return A value that is the size of the file in bytes.
     size_t getFileSize() { return _filesize; };
+
+    /// \brief Get the time of the last access.
+    ///
+    /// @return A real pointer to the struct timespec of the last access.
+    struct timespec *getLastAccessTime() { return &_last_access; };
     
-    ///  \brief Dump the internal data of this class in a human readable form.
+#ifdef USE_STATS_CACHE
+    /// \brief Get the time of the first access.
+    ///                This function should only be used for debugging and
+    ///                performance testing.
+    ///
+    /// @return A real pointer to the struct timespec of the last access.
+    struct timespec *getFirstAccessTime() { return &_first_access; };
+#endif    
+
+    /// \brief Dump the internal data of this class in a human readable form.
     /// @remarks This should only be used for debugging purposes.
     void dump() const { dump(std::cerr); }
     /// \overload dump(std::ostream& os) const
-    void dump(std::ostream& os) const;    
+    void dump(std::ostream& os) const;
 
 private:
     /// \var DiskStream::_state
     ///                The current status of the stream while streaming.
     state_e     _state;
-    int         _bytes;                // FIXME: is this a dup ?
     
     /// \var DiskStream::_filefd
     ///                The file descriptor of the disk file.
@@ -230,13 +245,21 @@
     ///                page.
     off_t      _offset;
     
-    gnash::CQue _que;
+    struct timespec _last_access;
+    
+#ifdef USE_STATS_CACHE
+    struct timespec _first_access;     // used for timing how long data stays 
in the queue.
+#endif
+
+#ifdef USE_STATS_FILE
+    int         _bytes;
+#endif
 };
 
 /// \brief Dump to the specified output stream.
-inline std::ostream& operator << (std::ostream& os, const DiskStream& cache)
+inline std::ostream& operator << (std::ostream& os, const DiskStream& ds)
 {
-       cache.dump(os);
+       ds.dump(os);
        return os;
 }
 

=== modified file 'libnet/http.cpp'
--- a/libnet/http.cpp   2008-11-06 22:43:21 +0000
+++ b/libnet/http.cpp   2008-11-15 03:17:57 +0000
@@ -50,6 +50,7 @@
 #include "utility.h"
 #include "buffer.h"
 #include "diskstream.h"
+#include "cache.h"
 
 using namespace gnash;
 using namespace std;
@@ -64,6 +65,8 @@
 // FIXME, this seems too small to me.  --gnu
 static const int readsize = 1024;
 
+static Cache& cache = Cache::getDefaultInstance();
+
 HTTP::HTTP() 
     : _filetype(amf::AMF::FILETYPE_HTML),
       _filesize(0),
@@ -165,6 +168,7 @@
 //    dump();
 
     _filespec = _url;
+
     if (!_url.empty()) {
        return true;
     }
@@ -1136,59 +1140,63 @@
 // Get the file type, so we know how to set the
 // Content-type in the header.
 amf::AMF::filetype_e
+
 HTTP::getFileStats(std::string &filespec)
 {
-//    GNASH_REPORT_FUNCTION;    
+    GNASH_REPORT_FUNCTION;    
     bool try_again = true;
     string actual_filespec = filespec;
     struct stat st;
 
-    while (try_again) {
-       try_again = false;
+    if (cache.findPath(filespec).empty()) {
+       while (try_again) {
+           try_again = false;
 //     cerr << "Trying to open " << actual_filespec << "\r\n";
-       if (stat(actual_filespec.c_str(), &st) == 0) {
-           // If it's a directory, then we emulate what apache
-           // does, which is to load the index.html file in that
-           // directry if it exists.
-           if (S_ISDIR(st.st_mode)) {
-               log_debug("%s is a directory\n", actual_filespec.c_str());
-               if (actual_filespec[actual_filespec.size()-1] != '/') {
-                   actual_filespec += '/';
-               }
-               actual_filespec += "index.html";
-               try_again = true;
-               continue;
-           } else {            // not a directory
-               log_debug("%s is not a directory\n", actual_filespec.c_str());
-               _filespec = actual_filespec;
-               string::size_type pos;
-               pos = filespec.rfind(".");
-               if (pos != string::npos) {
-                   string suffix = filespec.substr(pos, filespec.size());
-                   if (suffix == "html") {
-                       _filetype = amf::AMF::FILETYPE_HTML;
-                       log_debug("HTML content found");
-                   }
-                   if (suffix == "swf") {
-                       _filetype = amf::AMF::FILETYPE_SWF;
-                       log_debug("SWF content found");
-                   }
-                   if (suffix == "flv") {
-                       _filetype = amf::AMF::FILETYPE_VIDEO;
-                       log_debug("FLV content found");
-                   }
-                   if (suffix == "mp3") {
-                       _filetype = amf::AMF::FILETYPE_AUDIO;
-                       log_debug("MP3 content found");
-                   }
-               }
-           }
-       } else {
-           _filetype = amf::AMF::FILETYPE_ERROR;
-       } // end of stat()
-    } // end of try_waiting
-
-    _filesize = st.st_size;
+           if (stat(actual_filespec.c_str(), &st) == 0) {
+               // If it's a directory, then we emulate what apache
+               // does, which is to load the index.html file in that
+               // directry if it exists.
+               if (S_ISDIR(st.st_mode)) {
+                   log_debug("%s is a directory\n", actual_filespec.c_str());
+                   if (actual_filespec[actual_filespec.size()-1] != '/') {
+                       actual_filespec += '/';
+               }
+                   actual_filespec += "index.html";
+                   try_again = true;
+                   continue;
+               } else {                // not a directory
+                   log_debug("%s is not a directory\n", 
actual_filespec.c_str());
+                   _filespec = actual_filespec;
+                   string::size_type pos;
+                   pos = filespec.rfind(".");
+                   if (pos != string::npos) {
+                       string suffix = filespec.substr(pos, filespec.size());
+                       if (suffix == "html") {
+                           _filetype = amf::AMF::FILETYPE_HTML;
+                           log_debug("HTML content found");
+                       }
+                       if (suffix == "swf") {
+                           _filetype = amf::AMF::FILETYPE_SWF;
+                           log_debug("SWF content found");
+                       }
+                       if (suffix == "flv") {
+                           _filetype = amf::AMF::FILETYPE_VIDEO;
+                           log_debug("FLV content found");
+                       }
+                       if (suffix == "mp3") {
+                           _filetype = amf::AMF::FILETYPE_AUDIO;
+                           log_debug("MP3 content found");
+                       }
+                   }
+               }
+           } else {
+               _filetype = amf::AMF::FILETYPE_ERROR;
+           } // end of stat()
+       } // end of try_waiting
+       
+       _filesize = st.st_size;
+    }
+    
     return _filetype;
 }
 
@@ -1384,10 +1392,14 @@
        pos = url.find("?");
        filespec = url.substr(0, pos);
        parameters = url.substr(pos + 1, url.size());
-       // Get the file size for the HTTP header
+
+       if (cache.findPath(www.getFilespec()).empty()) {
+           cache.addPath(www.getFilespec(), filespec);
        
-       if (www.getFileStats(filespec) == amf::AMF::FILETYPE_ERROR) {
-           www.formatErrorResponse(HTTP::NOT_FOUND);
+           // Get the file size for the HTTP header
+           if (www.getFileStats(filespec) == amf::AMF::FILETYPE_ERROR) {
+               www.formatErrorResponse(HTTP::NOT_FOUND);
+           }
        }
        // Send the reply
 //     www.formatGetReply(HTTP::LIFE_IS_GOOD);
@@ -1409,11 +1421,19 @@
            filespec += "index.html";
        }
 
-       DiskStream filestream;
-       filestream.open(filespec);
-       boost::uint8_t *ptr = filestream.loadChunk();
+       DiskStream *filestream = cache.findFile(www.getFilespec());
+       if (filestream) {
+           cerr << "FIXME: found file!" << endl;
+       } else {
+           filestream = new DiskStream;
+       }
+       
+       filestream->open(filespec);
+       boost::uint8_t *ptr = filestream->loadChunk();
+       string response = cache.findResponse(www.getFilespec());
+       if (response.empty()) {
        www.clearHeader();
-       const stringstream &ss = www.formatHeader(filestream.getFileSize(), 
HTTP::LIFE_IS_GOOD);
+       const stringstream &ss = www.formatHeader(filestream->getFileSize(), 
HTTP::LIFE_IS_GOOD);
 //     cerr << "Size = " << ss.str().size() << "       " << ss.str() << endl;  
 //     string body = ss.str();
 //     cerr << "Body Size = " << body.size() << endl;
@@ -1423,8 +1443,16 @@
 //     //      cerr << "Size = " << ss.str().size() << "       " << ss.str() 
<< endl;
 //     www.writeNet(args->netfd, (boost::uint8_t *)body.c_str(), body.size());
        www.writeNet(args->netfd, (boost::uint8_t *)www.getHeader().c_str(), 
www.getHeader().size());
-       www.writeNet(args->netfd, filestream.get(), filestream.getFileSize());
+       cache.addResponse(www.getFilespec(), www.getHeader());
+       } else {
+//         cerr << "FIXME hit: " << www.getFilespec() << endl;
+           www.writeNet(args->netfd, (boost::uint8_t *)response.c_str(), 
response.size());
+       }       
+
+       www.writeNet(args->netfd, filestream->get(), filestream->getFileSize());
+       cache.addFile(www.getFilespec(), filestream);
        log_debug("http_handler all done now finally...");
+//     cache.dump();
        return;
 #if 0
        if (url != docroot) {


reply via email to

[Prev in Thread] Current Thread [Next in Thread]