Home | History | Annotate | Download | only in cache
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  ftcmru.h                                                               */
      4 /*                                                                         */
      5 /*    Simple MRU list-cache (specification).                               */
      6 /*                                                                         */
      7 /*  Copyright 2000-2018 by                                                 */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      9 /*                                                                         */
     10 /*  This file is part of the FreeType project, and may only be used,       */
     11 /*  modified, and distributed under the terms of the FreeType project      */
     12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     13 /*  this file you indicate that you have read the license and              */
     14 /*  understand and accept it fully.                                        */
     15 /*                                                                         */
     16 /***************************************************************************/
     17 
     18 
     19   /*************************************************************************/
     20   /*                                                                       */
     21   /* An MRU is a list that cannot hold more than a certain number of       */
     22   /* elements (`max_elements').  All elements in the list are sorted in    */
     23   /* least-recently-used order, i.e., the `oldest' element is at the tail  */
     24   /* of the list.                                                          */
     25   /*                                                                       */
     26   /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'),   */
     27   /* the list is searched for an element with the corresponding key.  If   */
     28   /* it is found, the element is moved to the head of the list and is      */
     29   /* returned.                                                             */
     30   /*                                                                       */
     31   /* If no corresponding element is found, the lookup routine will try to  */
     32   /* obtain a new element with the relevant key.  If the list is already   */
     33   /* full, the oldest element from the list is discarded and replaced by a */
     34   /* new one; a new element is added to the list otherwise.                */
     35   /*                                                                       */
     36   /* Note that it is possible to pre-allocate the element list nodes.      */
     37   /* This is handy if `max_elements' is sufficiently small, as it saves    */
     38   /* allocations/releases during the lookup process.                       */
     39   /*                                                                       */
     40   /*************************************************************************/
     41 
     42 
     43 #ifndef FTCMRU_H_
     44 #define FTCMRU_H_
     45 
     46 
     47 #include <ft2build.h>
     48 #include FT_FREETYPE_H
     49 
     50 #ifdef FREETYPE_H
     51 #error "freetype.h of FreeType 1 has been loaded!"
     52 #error "Please fix the directory search order for header files"
     53 #error "so that freetype.h of FreeType 2 is found first."
     54 #endif
     55 
     56 #define  xxFT_DEBUG_ERROR
     57 #define  FTC_INLINE
     58 
     59 FT_BEGIN_HEADER
     60 
     61   typedef struct FTC_MruNodeRec_*  FTC_MruNode;
     62 
     63   typedef struct  FTC_MruNodeRec_
     64   {
     65     FTC_MruNode  next;
     66     FTC_MruNode  prev;
     67 
     68   } FTC_MruNodeRec;
     69 
     70 
     71   FT_LOCAL( void )
     72   FTC_MruNode_Prepend( FTC_MruNode  *plist,
     73                        FTC_MruNode   node );
     74 
     75   FT_LOCAL( void )
     76   FTC_MruNode_Up( FTC_MruNode  *plist,
     77                   FTC_MruNode   node );
     78 
     79   FT_LOCAL( void )
     80   FTC_MruNode_Remove( FTC_MruNode  *plist,
     81                       FTC_MruNode   node );
     82 
     83 
     84   typedef struct FTC_MruListRec_*              FTC_MruList;
     85 
     86   typedef struct FTC_MruListClassRec_ const *  FTC_MruListClass;
     87 
     88 
     89   typedef FT_Bool
     90   (*FTC_MruNode_CompareFunc)( FTC_MruNode  node,
     91                               FT_Pointer   key );
     92 
     93   typedef FT_Error
     94   (*FTC_MruNode_InitFunc)( FTC_MruNode  node,
     95                            FT_Pointer   key,
     96                            FT_Pointer   data );
     97 
     98   typedef FT_Error
     99   (*FTC_MruNode_ResetFunc)( FTC_MruNode  node,
    100                             FT_Pointer   key,
    101                             FT_Pointer   data );
    102 
    103   typedef void
    104   (*FTC_MruNode_DoneFunc)( FTC_MruNode  node,
    105                            FT_Pointer   data );
    106 
    107 
    108   typedef struct  FTC_MruListClassRec_
    109   {
    110     FT_Offset                node_size;
    111 
    112     FTC_MruNode_CompareFunc  node_compare;
    113     FTC_MruNode_InitFunc     node_init;
    114     FTC_MruNode_ResetFunc    node_reset;
    115     FTC_MruNode_DoneFunc     node_done;
    116 
    117   } FTC_MruListClassRec;
    118 
    119 
    120   typedef struct  FTC_MruListRec_
    121   {
    122     FT_UInt              num_nodes;
    123     FT_UInt              max_nodes;
    124     FTC_MruNode          nodes;
    125     FT_Pointer           data;
    126     FTC_MruListClassRec  clazz;
    127     FT_Memory            memory;
    128 
    129   } FTC_MruListRec;
    130 
    131 
    132   FT_LOCAL( void )
    133   FTC_MruList_Init( FTC_MruList       list,
    134                     FTC_MruListClass  clazz,
    135                     FT_UInt           max_nodes,
    136                     FT_Pointer        data,
    137                     FT_Memory         memory );
    138 
    139   FT_LOCAL( void )
    140   FTC_MruList_Reset( FTC_MruList  list );
    141 
    142 
    143   FT_LOCAL( void )
    144   FTC_MruList_Done( FTC_MruList  list );
    145 
    146 
    147   FT_LOCAL( FT_Error )
    148   FTC_MruList_New( FTC_MruList   list,
    149                    FT_Pointer    key,
    150                    FTC_MruNode  *anode );
    151 
    152   FT_LOCAL( void )
    153   FTC_MruList_Remove( FTC_MruList  list,
    154                       FTC_MruNode  node );
    155 
    156   FT_LOCAL( void )
    157   FTC_MruList_RemoveSelection( FTC_MruList              list,
    158                                FTC_MruNode_CompareFunc  selection,
    159                                FT_Pointer               key );
    160 
    161 
    162 #ifdef FTC_INLINE
    163 
    164 #define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error )           \
    165   FT_BEGIN_STMNT                                                            \
    166     FTC_MruNode*             _pfirst  = &(list)->nodes;                     \
    167     FTC_MruNode_CompareFunc  _compare = (FTC_MruNode_CompareFunc)(compare); \
    168     FTC_MruNode              _first, _node;                                 \
    169                                                                             \
    170                                                                             \
    171     error  = FT_Err_Ok;                                                     \
    172     _first = *(_pfirst);                                                    \
    173     _node  = NULL;                                                          \
    174                                                                             \
    175     if ( _first )                                                           \
    176     {                                                                       \
    177       _node = _first;                                                       \
    178       do                                                                    \
    179       {                                                                     \
    180         if ( _compare( _node, (key) ) )                                     \
    181         {                                                                   \
    182           if ( _node != _first )                                            \
    183             FTC_MruNode_Up( _pfirst, _node );                               \
    184                                                                             \
    185           node = _node;                                                     \
    186           goto MruOk_;                                                      \
    187         }                                                                   \
    188         _node = _node->next;                                                \
    189                                                                             \
    190       } while ( _node != _first);                                           \
    191     }                                                                       \
    192                                                                             \
    193     error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \
    194   MruOk_:                                                                   \
    195     ;                                                                       \
    196   FT_END_STMNT
    197 
    198 #define FTC_MRULIST_LOOKUP( list, key, node, error ) \
    199   FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error )
    200 
    201 #else  /* !FTC_INLINE */
    202 
    203   FT_LOCAL( FTC_MruNode )
    204   FTC_MruList_Find( FTC_MruList  list,
    205                     FT_Pointer   key );
    206 
    207   FT_LOCAL( FT_Error )
    208   FTC_MruList_Lookup( FTC_MruList   list,
    209                       FT_Pointer    key,
    210                       FTC_MruNode  *pnode );
    211 
    212 #define FTC_MRULIST_LOOKUP( list, key, node, error ) \
    213   error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) )
    214 
    215 #endif /* !FTC_INLINE */
    216 
    217 
    218 #define FTC_MRULIST_LOOP( list, node )        \
    219   FT_BEGIN_STMNT                              \
    220     FTC_MruNode  _first = (list)->nodes;      \
    221                                               \
    222                                               \
    223     if ( _first )                             \
    224     {                                         \
    225       FTC_MruNode  _node = _first;            \
    226                                               \
    227                                               \
    228       do                                      \
    229       {                                       \
    230         *(FTC_MruNode*)&(node) = _node;
    231 
    232 
    233 #define FTC_MRULIST_LOOP_END()               \
    234         _node = _node->next;                 \
    235                                              \
    236       } while ( _node != _first );           \
    237     }                                        \
    238   FT_END_STMNT
    239 
    240  /* */
    241 
    242 FT_END_HEADER
    243 
    244 
    245 #endif /* FTCMRU_H_ */
    246 
    247 
    248 /* END */
    249