void Cache::insertDiskEntry(const std::string& k, FileEntry* v) 
{ 
   // If necessary, make space 
   while (_diskcache.size()>0 && 
         (_diskcache.size()>=_maxDiskCacheEntries || _curDiskCacheCapacity > _maxDiskCacheCapacity))
   {
      std::cout << "[CACHE] Deleting Disk Cache Entry: curSize = " << _curDiskCacheCapacity << ", max = " << _maxDiskCacheCapacity << "\n";

      FileEntry* pEntry = _diskcache.right.begin()->info;
      if (!pEntry->IsReady() && !pEntry->IsFailed())
      {
         return; // can't delete at the moment
      }
      
      // by purging the least-recently-used element 
      _curDiskCacheCapacity -= ((double)pEntry->FileSize() / 1024.0 / 1024.0);
      if (_curDiskCacheCapacity < 0)  _curDiskCacheCapacity = 0;

      // delete Cache entry from disk:
      std::string sFilename = _basedir + pEntry->LocalFile();
      std::string sCacheFile = sFilename + ".cache";
      
      if (!FileSystem::rm(sCacheFile)) std::cout << "**ERROR: Failed deleting: " << sCacheFile << "\n";  
      if (!FileSystem::rm(sFilename)) std::cout << "**ERROR: Failed deleting: " << sFilename << "\n";  

      // delete entry from list
      _diskcache.right.erase(_diskcache.right.begin()); 
   } 

   _diskcache.insert(DiskCache_t::value_type(k,0,v)); 
} 
MemoryEntry* Cache::_RequestData(const std::string& url, boost::function<void(const std::string&, MemoryEntry*, void*)> callback, bool async, void* userdata, boost::function<void(const std::string&, MemoryEntry*, void*)> callback_onthread)
{
   MemoryEntry* result = 0;
   int n = url.find("http://");
	if(n != 0)
   {
      result = _LoadLocalFile(url, async, false, callback, callback_onthread, url, userdata);
      return result;
   }
   else
   {
      // file on web -> disk cache required
      // Attempt to find record of the URL in disk cache
      const DiskCache_t::left_iterator it =_diskcache.left.find(url); 

      if (it==_diskcache.left.end()) 
      { 
          // create new record 
          FileEntry* v= new FileEntry();
          insertDiskEntry(url,v); 

          result = _LoadRemoteFile(url, v, async, callback, callback_onthread, userdata);
          return result;
      }
      else
      {
         // We do have it: 
         // Update the access record view. 
          
         FileEntry* entry = it->info; 
         if (!entry->IsFailed()) // failed entries never get higher
            _diskcache.right.relocate(_diskcache.right.end(), _diskcache.project_right(it));
         
         result = _LoadLocalFile(entry->LocalFile(), async, true, callback, callback_onthread, url, userdata);

         return result;
      }

   }

   return 0;
}
void Cache::dump(bool memonly)
{
   if (!memonly)
   {
   // DUMPING DISK CACHE
 
   std::cout << "***********************\n";
   std::cout << "*** DISK CACHE INFO ***\n";
   std::cout << "***********************\n";
   std::cout << "Capacity: " << _curDiskCacheCapacity << "\n";
   std::cout << "Disk cache has " << _diskcache.right.size() << " entries\n";

   DiskCache_t::right_const_iterator it = _diskcache.right.begin();

   while (it != _diskcache.right.end())
   {
      FileEntry* f = it->info;
      if (f->IsReady())
      {
        std::cout << "[READY] " << it->second << " (" << f->LocalFile() << ")\n";
      }
      else
      {
         if (f->IsFailed())
         {
            std::cout << "[FAILED] " << it->second << "\n";
         }
         else
         {
            std::cout << "[WAIT] " << it->second << "\n";
         } 
      }

      ++it;
   }

   }

   std::cout << "*************************\n";
   std::cout << "*** MEMORY CACHE INFO ***\n";
   std::cout << "*************************\n";
   std::cout << "Capacity: " << _curMemoryCacheCapacity << "\n";
   std::cout << "Memory cache has " << _memcache.right.size() << " entries\n";

   MemoryCache_t::right_const_iterator jt = _memcache.right.begin();

   while (jt != _memcache.right.end())
   {
      MemoryEntry* m = jt->info;

      if (m->IsReady())
      {
         std::cout << "[READY] " << jt->second << "  (" <<  m->DataSize() << " bytes)\n";
      }
      else
      {
         if (m->IsFailed())
         {
            std::cout << "[FAILED] " << jt->second << "\n";
         }
         else
         {
            std::cout << "[WAIT] " << jt->second << "\n";
         }
      }

      jt++;
   }

}