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

📄 ftlru.c

📁 qt-embedded-2.3.8.tar.gz源码
💻 C
字号:
/***************************************************************************//*                                                                         *//*  ftlru.c                                                                *//*                                                                         *//*    Simple LRU list-cache (body).                                        *//*                                                                         *//*  Copyright 2000 by                                                      *//*  David Turner, Robert Wilhelm, and Werner Lemberg.                      *//*                                                                         *//*  This file is part of the FreeType project, and may only be used,       *//*  modified, and distributed under the terms of the FreeType project      *//*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     *//*  this file you indicate that you have read the license and              *//*  understand and accept it fully.                                        *//*                                                                         *//***************************************************************************/#include <freetype/cache/ftlru.h>#include <freetype/ftlist.h>#include <freetype/internal/ftobjs.h>  static  void  lru_build_free_list( FT_LruNode  nodes,                             FT_UInt     count,                             FT_List     free_list )  {    FT_LruNode  node  = nodes;    FT_LruNode  limit = node + count;    free_list->head = free_list->tail = 0;    for ( ; node < limit; node++ )      FT_List_Add( free_list, (FT_ListNode)node );  }  FT_EXPORT_DEF( FT_Error )  FT_Lru_New( const FT_Lru_Class*  clazz,                                         FT_UInt              max_elements,                                         FT_Pointer           user_data,                                         FT_Memory            memory,                                         FT_Bool              pre_alloc,                                         FT_Lru              *anlru )  {    FT_Error  error;    FT_Lru    lru;    if ( !anlru )      return FT_Err_Invalid_Argument;    *anlru = 0;    if ( !ALLOC( lru, sizeof ( *lru ) ) )    {      if ( pre_alloc )      {        /* allocate static array of lru list nodes */        if ( ALLOC_ARRAY( lru->nodes, max_elements, FT_LruNodeRec ) )        {          FREE( lru );          goto Exit;        }        /* build the `free_nodes' list from the array */        lru_build_free_list( lru->nodes, max_elements, &lru->free_nodes );      }      /* initialize common fields */      lru->clazz        = (FT_Lru_Class*)clazz;      lru->max_elements = max_elements;      lru->memory       = memory;      lru->user_data    = user_data;      *anlru = lru;    }  Exit:    return error;  }  FT_EXPORT_DEF( void )  FT_Lru_Reset( FT_Lru  lru )  {    FT_ListNode    node;    FT_Lru_Class*  clazz;    FT_Memory      memory;    if ( !lru )      return;    node   = lru->elements.head;    clazz  = lru->clazz;    memory = lru->memory;    while ( node )    {      FT_ListNode  next = node->next;      clazz->done_element( lru, (FT_LruNode)node );      if ( !lru->nodes )        FREE( node );      node = next;    }    /* rebuild free list if necessary */    if ( lru->nodes )      lru_build_free_list( lru->nodes, lru->max_elements, &lru->free_nodes );    lru->elements.head = lru->elements.tail = 0;    lru->num_elements  = 0;  }  FT_EXPORT_DEF( void )  FT_Lru_Done( FT_Lru  lru )  {    FT_Memory  memory;    if ( !lru )      return;    memory = lru->memory;    FT_Lru_Reset( lru );    FREE( lru );  }  FT_EXPORT_DEF( FT_Error )  FT_Lru_Lookup_Node( FT_Lru       lru,                                                 FT_LruKey    key,                                                 FT_LruNode  *anode )  {    FT_Error       error = 0;    FT_ListNode    node;    FT_Lru_Class*  clazz;    FT_LruNode     found = 0;    FT_Memory      memory;    if ( !lru || !key || !anode )      return FT_Err_Invalid_Argument;    node   = lru->elements.head;    clazz  = lru->clazz;    memory = lru->memory;    if ( clazz->compare_element )    {      for ( ; node; node = node->next )        if ( clazz->compare_element( (FT_LruNode)node, key ) )        {          found = (FT_LruNode)node;          break;        }    }    else    {      for ( ; node; node = node->next )        if ( ((FT_LruNode)node)->key == key )        {          found = (FT_LruNode)node;          break;        }    }    if ( !found )    {      /* we haven't found the relevant element.  We will now try */      /* to create a new one.                                    */      if ( lru->num_elements >= lru->max_elements )      {        /* this lru list is full; we will now flush */        /* the oldest node                          */        FT_LruNode  lru_node;        node     = lru->elements.tail;        lru_node = (FT_LruNode)node;        found    = lru_node;        if ( clazz->flush_element )          error = clazz->flush_element( lru, lru_node, key );        else        {          clazz->done_element( lru, lru_node );          lru_node->key = key;          node->data    = 0;          error = clazz->init_element( lru, lru_node );        }        if ( !error )        {          /* now, move element to top of list */          FT_List_Up( &lru->elements, node );        }        else        {          /* in case of error, the node must be discarded */          FT_List_Remove( &lru->elements, node );          lru->num_elements--;          if ( lru->nodes )            FT_List_Insert( &lru->free_nodes, node );          else            FREE( lru_node );          found = 0;        }      }      else      {        FT_LruNode  lru_node;        /* create a new lru list node, then the element for it */        if ( lru->nodes )        {          node          = lru->free_nodes.head;          lru_node      = (FT_LruNode)node;          lru_node->key = key;          error = clazz->init_element( lru, lru_node );          if ( error )            goto Exit;          FT_List_Remove( &lru->free_nodes, node );        }        else        {          if ( ALLOC( lru_node, sizeof ( *lru_node ) ) )            goto Exit;          lru_node->key = key;          error = clazz->init_element( lru, lru_node );          if ( error )          {            FREE( lru_node );            goto Exit;          }        }        found = lru_node;        node  = (FT_ListNode)lru_node;        FT_List_Insert( &lru->elements, node );        lru->num_elements++;      }    }  Exit:    *anode = found;    return error;  }  FT_EXPORT_DEF( FT_Error )  FT_Lru_Lookup( FT_Lru       lru,                                            FT_LruKey    key,                                            FT_Pointer  *anobject )  {    FT_Error    error;    FT_LruNode  node;    /* check for valid `lru' and `key' delayed to FT_Lru_Lookup_Node() */    if ( !anobject )      return FT_Err_Invalid_Argument;    *anobject = 0;    error = FT_Lru_Lookup_Node( lru, key, &node );    if ( !error )      *anobject = node->root.data;    return error;  }  FT_EXPORT_DEF( void )  FT_Lru_Remove_Node( FT_Lru      lru,                                             FT_LruNode  node )  {    if ( !lru || !node )      return;    if ( lru->num_elements > 0 )    {      FT_List_Remove( &lru->elements, (FT_ListNode)node );      lru->clazz->done_element( lru, node );      if ( lru->nodes )        FT_List_Insert( &lru->free_nodes, (FT_ListNode)node );      else      {        FT_Memory  memory = lru->memory;        FREE( node );      }      lru->num_elements--;    }  }  FT_EXPORT_DEF( void )  FT_Lru_Remove_Selection( FT_Lru           lru,                                                  FT_Lru_Selector  selector,                                                  FT_Pointer       data )  {    if ( !lru || !selector )      return;    if ( lru->num_elements > 0 )    {      FT_ListNode  node = lru->elements.head;      FT_ListNode  next;      while ( node )      {        next = node->next;        if ( selector( lru, (FT_LruNode)node, data ) )        {          /* remove this element from the list, and destroy it */          FT_Lru_Remove_Node( lru, (FT_LruNode)node );        }        node = next;      }    }  }/* END */

⌨️ 快捷键说明

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