#include <mcache.h>
Inheritance diagram for MediaCache:


Public Member Functions | |
| MediaCache () | |
| ~MediaCache () | |
| virtual void | process_data (int size, AppData *data) |
| virtual AppData * | get_data (int &size, AppData *data) |
| void | log (const char *fmt,...) |
| int | id () const |
| Process *& | target () |
| virtual void | send_data (int size, AppData *data=0) |
Protected Types | |
| enum | { NOPREF, ONLINE_PREF, OFFLINE_PREF } |
Protected Member Functions | |
| virtual int | command (int argc, const char *const *argv) |
| MClientPagePool * | mpool () |
| int | add_cnc (HttpApp *client, TcpApp *agt) |
| void | delete_cnc (HttpApp *client) |
| TcpApp * | lookup_cnc (HttpApp *client) |
| void | set_pagepool (ClientPagePool *pp) |
Protected Attributes | |
| Tcl_HashTable * | cmap_ |
| enum MediaCache:: { ... } | pref_style_ |
| Tcl_HashTable * | tpa_ |
| int | id_ |
| ClientPagePool * | pool_ |
| Tcl_Channel | log_ |
| Process * | target_ |
|
|
Definition at line 297 of file mcache.h.
00297 {NOPREF, ONLINE_PREF, OFFLINE_PREF} pref_style_;
|
|
|
Definition at line 756 of file mcache.cc. References cmap_.
00756 : pref_style_(ONLINE_PREF) 00757 { 00758 cmap_ = new Tcl_HashTable; 00759 Tcl_InitHashTable(cmap_, TCL_ONE_WORD_KEYS); 00760 } |
|
|
Definition at line 762 of file mcache.cc. References cmap_.
|
|
||||||||||||
|
Definition at line 69 of file http.cc. References client, and HttpApp::tpa_. Referenced by HttpApp::command().
00070 {
00071 int newEntry = 1;
00072 Tcl_HashEntry *he = Tcl_CreateHashEntry(tpa_,
00073 (const char *)client->id(),
00074 &newEntry);
00075 if (he == NULL)
00076 return -1;
00077 if (newEntry)
00078 Tcl_SetHashValue(he, (ClientData)agt);
00079 return 0;
00080 }
|
|
||||||||||||
|
Reimplemented from HttpApp. Definition at line 922 of file mcache.cc. References MediaCache::RegInfo::client_, cmap_, HttpApp::command(), MediaCache::RegInfo::db_, MClientPagePool::dump_hclist(), MediaCache::RegInfo::eb_, MClientPagePool::fill_page(), ClientPagePool::get_page(), MClientPagePool::hc_update(), MediaCache::RegInfo::hl_, HttpApp::id_, HttpApp::log(), MEDIA, mpool(), MediaCache::RegInfo::name_, NOPREF, MediaPage::num_layer(), OFFLINE_PREF, ONLINE_PREF, MediaCache::RegInfo::pb_, pref_style_, MediaPage::print_layer(), MediaPage::tlock(), MediaPage::tunlock(), MediaPage::type(), ClientPage::type(), and MediaPage::unlock().
00923 {
00924 Tcl& tcl = Tcl::instance();
00925 if (argc == 2) {
00926 if (strcmp(argv[1], "get-pref-style") == 0) {
00927 switch (pref_style_) {
00928 case NOPREF:
00929 tcl.result("NOPREF");
00930 break;
00931 case ONLINE_PREF:
00932 tcl.result("ONLINE_PREF");
00933 break;
00934 case OFFLINE_PREF:
00935 tcl.result("OFFLINE_PREF");
00936 break;
00937 default:
00938 fprintf(stderr,
00939 "Corrupted prefetching style %d",
00940 pref_style_);
00941 return TCL_ERROR;
00942 }
00943 return TCL_OK;
00944 }
00945 } else if (argc == 3) {
00946 if (strcmp(argv[1], "offline-complete") == 0) {
00947 // Delete whatever segments in the given page,
00948 // make it complete. Used by offline prefetching
00949 ClientPage *pg = mpool()->get_page(argv[2]);
00950 if (pg == NULL)
00951 // XXX It's possible that we've already kicked
00952 // it out of the cache. Do nothing.
00953 return TCL_OK;
00954 assert(pg->type() == MEDIA);
00955 assert(!((MediaPage*)pg)->is_locked());
00956 mpool()->fill_page(argv[2]);
00957 return TCL_OK;
00958 } else if (strcmp(argv[1], "set-pref-style") == 0) {
00959 // Set prefetching style
00960 // <obj> set-pref-style <style>
00961 //
00962 // style can be: NOPREF, ONLINE_PREF, OFFLINE_PREF
00963 if (strcmp(argv[2], "NOPREF") == 0)
00964 pref_style_ = NOPREF;
00965 else if (strcmp(argv[2], "ONLINE_PREF") == 0)
00966 pref_style_ = ONLINE_PREF;
00967 else if (strcmp(argv[2], "OFFLINE_PREF") == 0)
00968 pref_style_ = OFFLINE_PREF;
00969 else {
00970 fprintf(stderr, "Wrong prefetching style %s",
00971 argv[2]);
00972 return TCL_ERROR;
00973 }
00974 return TCL_OK;
00975 } else if (strcmp(argv[1], "dump-page") == 0) {
00976 // Dump segments of a given page
00977 ClientPage *p=(ClientPage*)mpool()->get_page(argv[2]);
00978 if (p->type() != MEDIA)
00979 // Do nothing for non-media pages
00980 return TCL_OK;
00981 MediaPage *pg = (MediaPage *)p;
00982 char *buf;
00983 for (int i = 0; i < pg->num_layer(); i++) {
00984 buf = pg->print_layer(i);
00985 if (strlen(buf) > 0)
00986 log("E SEGS p %s l %d %s\n", argv[2],
00987 i, buf);
00988 delete []buf;
00989 }
00990 return TCL_OK;
00991 } else if (strcmp(argv[1], "stream-received") == 0) {
00992 // We've got the entire page, unlock it
00993 MediaPage *pg = (MediaPage*)mpool()->get_page(argv[2]);
00994 assert(pg != NULL);
00995 pg->unlock();
00996 // XXX Should we clear all "last" flag of segments??
00997 #ifdef MCACHE_DEBUG
00998 // Printing out current buffer status of the page
00999 char *buf;
01000 for (int i = 0; i < pg->num_layer(); i++) {
01001 buf = pg->print_layer(i);
01002 log("E SEGS p %s l %d %s\n", argv[2], i, buf);
01003 delete []buf;
01004 }
01005 #endif
01006 // Show cache free size
01007 log("E SIZ n %d z %d t %d\n", mpool()->num_pages(),
01008 mpool()->usedsize(), mpool()->maxsize());
01009 return TCL_OK;
01010 }
01011 } else if (argc == 5) {
01012 if (strcmp(argv[1], "register-client") == 0) {
01013 // <server> register-client <app> <client> <pageid>
01014 TclObject *a = TclObject::lookup(argv[2]);
01015 assert(a != NULL);
01016 int newEntry;
01017 Tcl_HashEntry *he = Tcl_CreateHashEntry(cmap_,
01018 (const char *)a, &newEntry);
01019 if (he == NULL) {
01020 tcl.add_errorf("cannot create hash entry");
01021 return TCL_ERROR;
01022 }
01023 if (!newEntry) {
01024 tcl.add_errorf("duplicate connection");
01025 return TCL_ERROR;
01026 }
01027 RegInfo *p = new RegInfo;
01028 p->client_ = (HttpApp*)TclObject::lookup(argv[3]);
01029 assert(p->client_ != NULL);
01030 strcpy(p->name_, argv[4]);
01031 Tcl_SetHashValue(he, (ClientData)p);
01032
01033 // Lock the page while transmitting it to a client
01034 MediaPage *pg = (MediaPage*)mpool()->get_page(argv[4]);
01035 assert((pg != NULL) && (pg->type() == MEDIA));
01036 pg->tlock();
01037
01038 return TCL_OK;
01039 } else if (strcmp(argv[1], "unregister-client") == 0) {
01040 // <server> unregister-client <app> <client> <pageid>
01041 TclObject *a = TclObject::lookup(argv[2]);
01042 assert(a != NULL);
01043 Tcl_HashEntry *he =
01044 Tcl_FindHashEntry(cmap_, (const char*)a);
01045 if (he == NULL) {
01046 tcl.add_errorf("cannot find hash entry");
01047 return TCL_ERROR;
01048 }
01049 RegInfo *ri = (RegInfo*)Tcl_GetHashValue(he);
01050 // Update hit count
01051 mpool()->hc_update(argv[4], ri->hl_);
01052 #ifdef MCACHE_DEBUG
01053 printf("Cache %d hit counts: \n", id_);
01054 mpool()->dump_hclist();
01055 #endif
01056 // Dump per-connection statistics
01057 for (int i = 0; i <= ri->hl_; i++)
01058 log("E STAT p %s l %d d %d e %d p %d\n",
01059 ri->name_, i, ri->db_[i], ri->eb_[i],
01060 ri->pb_[i]);
01061 delete ri;
01062 Tcl_DeleteHashEntry(he);
01063
01064 // Lock the page while transmitting it to a client
01065 MediaPage *pg = (MediaPage*)mpool()->get_page(argv[4]);
01066 assert((pg != NULL) && (pg->type() == MEDIA));
01067 pg->tunlock();
01068
01069 return TCL_OK;
01070 }
01071 }
01072
01073 return HttpCache::command(argc, argv);
01074 }
|
Here is the call graph for this function:

|
|
Definition at line 82 of file http.cc. References client, and HttpApp::tpa_. Referenced by HttpApp::command().
|
|
||||||||||||
|
Reimplemented from HttpApp. Definition at line 775 of file mcache.cc. References abort(), MediaRequest::app(), cmap_, MediaSegment::datasize(), MediaCache::RegInfo::db_, MediaSegmentList::destroy(), MediaSegmentList::dump2buf(), MediaCache::RegInfo::eb_, MediaSegment::end(), MediaRequest::et(), HttpApp::get_data(), ClientPagePool::get_page(), MediaCache::RegInfo::hl_, MediaPage::is_available(), MediaSegment::is_last(), MediaPage::is_locked(), MediaRequest::layer(), MediaSegmentList::length(), MEDIA_REQUEST, MEDIAREQ_CHECKSEG, MEDIAREQ_GETSEG, MediaRequest::name(), MediaPage::next_overlap(), ONLINE_PREF, HttpApp::pool_, MediaCache::RegInfo::pref_size(), pref_style_, req, MediaRequest::request(), HttpMediaData::set_finish(), HttpMediaData::set_last(), MediaRequest::st(), and MediaSegment::start().
00776 {
00777 assert(req != NULL);
00778 if (req->type() != MEDIA_REQUEST) {
00779 return HttpApp::get_data(size, req);
00780 }
00781
00782 MediaRequest *r = (MediaRequest *)req;
00783
00784 // Get statistics block for the requestor
00785 Tcl_HashEntry *he =
00786 Tcl_FindHashEntry(cmap_, (const char *)(r->app()));
00787 assert(he != NULL);
00788 RegInfo *ri = (RegInfo *)Tcl_GetHashValue(he);
00789
00790 // Process request
00791 if (r->request() == MEDIAREQ_GETSEG) {
00792 // Get a new data segment
00793 MediaPage* pg = (MediaPage*)pool_->get_page(r->name());
00794 assert(pg != NULL);
00795 MediaSegment s1(r->st(), r->et());
00796 MediaSegment s2 = pg->next_overlap(r->layer(), s1);
00797 HttpMediaData *p;
00798 if (s2.datasize() == 0) {
00799 // No more data available for this layer, allocate
00800 // an ADU with data size 0 to signal the end
00801 // of transmission for this layer
00802 size = 0;
00803 p = new HttpMediaData(name(), r->name(),
00804 r->layer(), 0, 0);
00805 } else {
00806 size = s2.datasize();
00807 p = new HttpMediaData(name(), r->name(),
00808 r->layer(), s2.start(), s2.end());
00809 }
00810 // XXX If we are still receiving the stream, don't
00811 // ever say that this is the last segment. If the
00812 // page is not locked, it's still possible that we
00813 // return a NULL segment because the requested one
00814 // is not available. Don't set the 'LAST' flag in this
00815 // case.
00816 if (s2.is_last()) {
00817 p->set_last();
00818 if (!pg->is_locked() && (s2.datasize() == 0) &&
00819 (r->layer() == 0))
00820 p->set_finish();
00821 }
00822
00823 //----------------------------------------
00824 // Update statistics of this connection
00825 //----------------------------------------
00826 // Update the highest layer that this client has requested
00827 if (ri->hl_ < r->layer())
00828 ri->hl_ = r->layer();
00829 if (size > 0) {
00830 // Update total delivered bytes
00831 ri->db_[r->layer()] += size;
00832 // Update prefetched bytes that've been delivered
00833 ri->eb_[r->layer()] += ri->pref_size(r->layer(), s2);
00834 }
00835 return p;
00836 } else if (r->request() == MEDIAREQ_CHECKSEG) {
00837 // If we are not doing online prefetching, return nothing
00838 if (pref_style_ != ONLINE_PREF)
00839 return NULL;
00840 // Check the availability of a new data segment
00841 // And refetch if it is not available
00842 MediaPage* pg = (MediaPage*)pool_->get_page(r->name());
00843 assert(pg != NULL);
00844 if (pg->is_locked())
00845 // If we are during the first retrieval, don't prefetch
00846 return NULL;
00847 MediaSegmentList ul = pg->is_available(r->layer(),
00848 MediaSegment(r->st(),r->et()));
00849 if (ul.length() == 0)
00850 // All segments are available
00851 return NULL;
00852 // Otherwise do prefetching on these "holes"
00853 char *buf = ul.dump2buf();
00854 Tcl::instance().evalf("%s pref-segment %s %s %d %s", name(),
00855 r->app()->name(), r->name(),
00856 r->layer(), buf);
00857 // log("E PREF p %s l %d %s\n", r->name(), r->layer(), buf);
00858 delete []buf;
00859 ul.destroy();
00860
00861 // Update the highest layer that this client has requested
00862 Tcl_HashEntry *he =
00863 Tcl_FindHashEntry(cmap_, (const char *)(r->app()));
00864 assert(he != NULL);
00865 RegInfo *ri = (RegInfo *)Tcl_GetHashValue(he);
00866 if (ri->hl_ < r->layer())
00867 ri->hl_ = r->layer();
00868 return NULL;
00869 }
00870
00871 fprintf(stderr,
00872 "MediaCache %s gets an unknown MediaRequest type %d\n",
00873 name(), r->request());
00874 abort();
00875 return NULL; // Make msvc happy
00876 }
|
Here is the call graph for this function:

|
|
Definition at line 44 of file http.h. References HttpApp::id_. Referenced by HttpMInvalCache::add_cache(), HttpMInvalCache::add_nbr(), HttpMInvalCache::command(), MediaServer::get_piq(), ClientPagePool::invalidate_server(), and HttpMInvalCache::process_inv().
00044 { return id_; }
|
|
||||||||||||
|
Definition at line 356 of file http.cc. References HttpApp::id_, Scheduler::instance(), HttpApp::log_, BaseTrace::round(), and TIME_FORMAT. Referenced by MediaClient::command(), command(), HttpMInvalCache::command(), HttpYucInvalServer::command(), MediaClient::process_data(), process_data(), HttpMInvalCache::process_inv(), and HttpMInvalCache::recv_upd().
00357 {
00358 // Don't do anything if we don't have a log file.
00359 if (log_ == 0)
00360 return;
00361
00362 char buf[10240], *p;
00363 sprintf(buf, TIME_FORMAT" i %d ",
00364 BaseTrace::round(Scheduler::instance().clock()), id_);
00365 p = &(buf[strlen(buf)]);
00366 va_list ap;
00367 va_start(ap, fmt);
00368 vsprintf(p, fmt, ap);
00369 Tcl_Write(log_, buf, strlen(buf));
00370 }
|
Here is the call graph for this function:

|
|
Definition at line 92 of file http.cc. References client, and HttpApp::tpa_. Referenced by HttpApp::command().
|
|
|
Definition at line 259 of file mcache.h. References HttpApp::pool_. Referenced by command(), and process_data().
00259 { return (MClientPagePool *)pool_; }
|
|
||||||||||||
|
Reimplemented from HttpApp. Definition at line 879 of file mcache.cc. References abort(), MediaCache::RegInfo::add_pref(), MClientPagePool::add_segment(), cmap_, HttpMediaData::conid(), HttpMediaData::datasize(), HttpMediaData::et(), HttpMediaData::is_pref(), HttpMediaData::layer(), HttpApp::log(), MEDIA_DATA, mpool(), HttpMediaData::page(), MediaCache::RegInfo::pb_, HttpApp::process_data(), HttpMediaData::st(), and AppData::type().
00880 {
00881 switch (data->type()) {
00882 case MEDIA_DATA: {
00883 HttpMediaData* d = (HttpMediaData*)data;
00884 // Cache this segment, do replacement if necessary
00885 if (mpool()->add_segment(d->page(), d->layer(),
00886 MediaSegment(*d)) == -1) {
00887 fprintf(stderr, "MediaCache %s gets a segment for an "
00888 "unknown page %s\n", name(), d->page());
00889 abort();
00890 }
00891 if (d->is_pref()) {
00892 // Update total prefetched bytes
00893 Tcl_HashEntry *he = Tcl_FindHashEntry(cmap_,
00894 (const char*)(d->conid()));
00895 // Client-cache-server disconnection procedure:
00896 // (1) client disconnects from cache, then
00897 // (2) cache disconnects from server and shuts down
00898 // prefetching channel.
00899 // Therefore, after client disconnects, the cache
00900 // may still receive a few prefetched segments.
00901 // Ignore those because we no longer keep statistics
00902 // about the torn-down connection.
00903 if (he != NULL) {
00904 RegInfo *ri = (RegInfo *)Tcl_GetHashValue(he);
00905 ri->add_pref(d->layer(), MediaSegment(*d));
00906 ri->pb_[d->layer()] += d->datasize();
00907 }
00908 }
00909 // XXX debugging only
00910 #if 1
00911 log("E RSEG p %s l %d s %d e %d z %d f %d\n",
00912 d->page(), d->layer(), d->st(), d->et(), d->datasize(),
00913 d->is_pref());
00914 #endif
00915 break;
00916 }
00917 default:
00918 HttpCache::process_data(size, data);
00919 }
00920 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 106 of file ns-process.h. References Process::process_data(), and Process::target_. Referenced by TcpApp::process_data(), and MediaApp::process_data().
00106 {
00107 if (target_)
00108 target_->process_data(size, data);
00109 }
|
Here is the call graph for this function:

|
|
Definition at line 58 of file http.h. References HttpApp::pool_.
00058 { pool_ = pp; }
|
|
|
Definition at line 97 of file ns-process.h. References Process::target_. Referenced by QA::check_availability(), Process::command(), HttpApp::command(), MediaApp::get_data(), QA::output(), and TcpApp::process_data().
00097 { return target_; }
|
|
|
Definition at line 294 of file mcache.h. Referenced by command(), get_data(), MediaCache(), process_data(), and ~MediaCache(). |
|
|
|
Definition at line 63 of file http.h. Referenced by HttpApp::command(), and HttpApp::log(). |
|
|
|
Referenced by command(), and get_data(). |
|
|
Definition at line 113 of file ns-process.h. Referenced by HttpUInvalAgent::command(), Process::Process(), HttpUInvalAgent::process_data(), Process::send_data(), and Process::target(). |
|
|
Definition at line 60 of file http.h. Referenced by HttpApp::add_cnc(), HttpApp::delete_cnc(), HttpApp::HttpApp(), HttpApp::lookup_cnc(), and HttpApp::~HttpApp(). |
1.3.3