⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aflibmemcache.cc

📁 一个共享源码的音频库2
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Copyright: (C) 2001 Bruce W. Forsberg * *   This library is free software; you can redistribute it and/or *   modify it under the terms of the GNU Lesser General Public *   License as published by the Free Software Foundation; either *   version 2.1 of the License, or any later version. * *   This library is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *   Lesser General Public License for more details. * *   You should have received a copy of the GNU Lesser General Public *   License along with this library; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA * *   Bruce Forsberg  forsberg@tns.net * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "aflibMemCache.h"#include "aflibMemNode.h"#include "aflib.h"#include "aflibData.h"#define CACHE_SIZE_MAX 1 * 1024 * 1024  // Max cache size totallong long aflibMemCache::_cache_size_total = 0;/*! \brief Constructor.*/aflibMemCache::aflibMemCache(){   _cache_counter = 0;   _cache_size_local = 0;   _enable = FALSE;   if (getenv("AFLIB_CACHE_SIZE"))      _cache_size_max = atoi(getenv("AFLIB_CACHE_SIZE"));   else      _cache_size_max = CACHE_SIZE_MAX;}/*! \brief Destructor.*/aflibMemCache::~aflibMemCache(){   clearCache();}/*! \brief Returns the current state of caching for this object.    Return the state of the cache. TRUE means caching is enabled.*/boolaflibMemCache::getCacheEnable(){   return(_enable);}/*! \brief Set the state of caching for this object.*/voidaflibMemCache::setCacheEnable(bool enable){   _enable = enable;}/*! \brief Returns the maximum allowed size of the cache.*/long longaflibMemCache::getCacheMax() const{   return (_cache_size_max);}/*! \brief Gets the current size of the cache for this object only.*/ long longaflibMemCache::getCacheLocal() const{   return (_cache_size_local);}/*! \brief Gets the total size of all caches added together.*/long longaflibMemCache::getCacheTotal() const{   return (_cache_size_total);}voidaflibMemCache::cacheData(   long long position,   aflibData& data){   // This function will receive a block of data to be cached. This function will store the   // data into the cache so that it can be read later. It will first of all check the   // cache size. If the cache limit has been exceeded then old data will be discarded.   // IF we have exceeded the max cache size then reduce the cache size   if (_cache_size_local > _cache_size_max)   {      reduceCache();   }   // Check if the data can replace an existing nodes data   if (!checkExistingNode(position, data))   {      // Create new node and insert into array      createNewNode(0, data.getLength(), position, data);   }} voidaflibMemCache::lookupData(   long long& position,   int& num_samples){   // This function will determine if there is data available in the cache that can be   // used. It will modify the position and num_samples passed in to indicate the data   // that is still needed that is not in the cache. If all the needed data is in the   // cache then this function will return num_samples equal to 0.	if(position == -1) return;   map< long long, aflibMemNode* >::iterator it;   map< long long, aflibMemNode* >::iterator it_prev;   bool processed = FALSE;   // loop thru all memory nodes   for (it = _node_array.begin(); it != _node_array.end(); it++)   {      // Loop until we find tbe memory node past the start of this memory location      if ((*it).first > position)      {         processed = TRUE;         // If no node before this position then no data in cache for this position         if (it == _node_array.begin())         {            break;         }         // IF data is not in node then done         if (position > (*it_prev).first + (long long)(*it_prev).second->getSize())         {            break;         }         // Use the previous node to modify data         calcPosition(position, num_samples, it_prev);         break;      }      it_prev = it;   }   // Check the last node if none others were found   if ((_node_array.size() != 0) && processed == FALSE)   {      calcPosition(position, num_samples, it_prev);   }}voidaflibMemCache::calcPosition(   long long& position,   int&       num_samples,   map< long long, aflibMemNode* >::iterator it){   // Using the memory node passed in modify the position and num_samples based on   // how much data can be retrieved from this node   int  diff;   // Find the amount of data that might be available   diff = (int) ( (*it).first + (*it).second->getSize() - position );    // IF there is data that we can use   if (diff > 0)   {      // IF all data is available      if (diff >= num_samples)      {         position += num_samples;         num_samples = 0;      }      else      {         position += diff;         num_samples -= diff;      }   }}voidaflibMemCache::reduceCache(){   // One or more nodes should be removed to keep memory usage in check.   // Currently this uses a very simple algorithm. It deletes the nodes with   // the smallest positions. This needs to change in the future.   long long size;   map< long long, aflibMemNode* >::iterator it;   // Delete cache nodes until local cache is less than max   while (_cache_size_local > _cache_size_max)   {      it = _node_array.begin();      // reduce total cache size of node      size = ((*it).second->getSize() * (*it).second->getChannels() * 4);      _cache_size_local -= size;      _cache_size_total -= size;      // Remove node      delete (*it).second;      _node_array.erase(it);   }}boolaflibMemCache::checkExistingNode(   long long position,   aflibData& data){   // This will check if the data can replace an existing node. If it does then TRUE   // will be returned. There are three possible cases that are covered in this function.   // They are cased on the following diagram.   //   //             |---New Data---|   //   // Case 1  |----------|   // Case 2  |---------------------|   // Case 3              |---->   //   // Case 1 is the existing node starts before the new data node and ends before the   // new data node ends.   // Case 2 is the existing node starts before the new data node and ends after the   // new data node ends.   // Case 3 is the existing node starts after the new data node and ends either before   // or after the new node ends.   //   // node_position and node_size are the position and sizes of the current node that we   // are iterating on. size and position is the size and position of the new data that   // is to be added. size and position can change as we add data to an existing node.   // orig_position and orig size is the original size and position of the new data and   // does not change.   map< long long, aflibMemNode* >::iterator it;   bool processed = FALSE;   long long node_position;   long long node_size;   long long size;   long long orig_position;   long long orig_size;   int  i, j;   int  chans;   chans = data.getConfig().getChannels();   size = data.getLength();   orig_position = position;   orig_size = size;    // Loop thru all nodes    for (it = _node_array.begin(); it != _node_array.end(); it++)   {      node_position = (*it).first;      node_size = (*it).second->getSize();      // IF end point of node is beyond new data start then      if (node_position + node_size > position)      {         // IF beginning point of node is before or equal new data start         if (node_position <= position)         {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -