PageRenderTime 38ms CodeModel.GetById 13ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/freetype/src/cache/ftcmru.c

https://bitbucket.org/cabalistic/ogredeps/
C | 357 lines | 252 code | 88 blank | 17 comment | 52 complexity | e55c0ad255d1a918d2dd91dae9deab1c MD5 | raw file
  1/***************************************************************************/
  2/*                                                                         */
  3/*  ftcmru.c                                                               */
  4/*                                                                         */
  5/*    FreeType MRU support (body).                                         */
  6/*                                                                         */
  7/*  Copyright 2003, 2004, 2006, 2009 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#include <ft2build.h>
 20#include FT_CACHE_H
 21#include "ftcmru.h"
 22#include FT_INTERNAL_OBJECTS_H
 23#include FT_INTERNAL_DEBUG_H
 24
 25#include "ftcerror.h"
 26
 27
 28  FT_LOCAL_DEF( void )
 29  FTC_MruNode_Prepend( FTC_MruNode  *plist,
 30                       FTC_MruNode   node )
 31  {
 32    FTC_MruNode  first = *plist;
 33
 34
 35    if ( first )
 36    {
 37      FTC_MruNode  last = first->prev;
 38
 39
 40#ifdef FT_DEBUG_ERROR
 41      {
 42        FTC_MruNode  cnode = first;
 43
 44
 45        do
 46        {
 47          if ( cnode == node )
 48          {
 49            fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" );
 50            exit( 2 );
 51          }
 52          cnode = cnode->next;
 53
 54        } while ( cnode != first );
 55      }
 56#endif
 57
 58      first->prev = node;
 59      last->next  = node;
 60      node->next  = first;
 61      node->prev  = last;
 62    }
 63    else
 64    {
 65      node->next = node;
 66      node->prev = node;
 67    }
 68    *plist = node;
 69  }
 70
 71
 72  FT_LOCAL_DEF( void )
 73  FTC_MruNode_Up( FTC_MruNode  *plist,
 74                  FTC_MruNode   node )
 75  {
 76    FTC_MruNode  first = *plist;
 77
 78
 79    FT_ASSERT( first != NULL );
 80
 81    if ( first != node )
 82    {
 83      FTC_MruNode  prev, next, last;
 84
 85
 86#ifdef FT_DEBUG_ERROR
 87      {
 88        FTC_MruNode  cnode = first;
 89        do
 90        {
 91          if ( cnode == node )
 92            goto Ok;
 93          cnode = cnode->next;
 94
 95        } while ( cnode != first );
 96
 97        fprintf( stderr, "FTC_MruNode_Up: invalid action\n" );
 98        exit( 2 );
 99      Ok:
100      }
101#endif
102      prev = node->prev;
103      next = node->next;
104
105      prev->next = next;
106      next->prev = prev;
107
108      last = first->prev;
109
110      last->next  = node;
111      first->prev = node;
112
113      node->next = first;
114      node->prev = last;
115
116      *plist = node;
117    }
118  }
119
120
121  FT_LOCAL_DEF( void )
122  FTC_MruNode_Remove( FTC_MruNode  *plist,
123                      FTC_MruNode   node )
124  {
125    FTC_MruNode  first = *plist;
126    FTC_MruNode  prev, next;
127
128
129    FT_ASSERT( first != NULL );
130
131#ifdef FT_DEBUG_ERROR
132      {
133        FTC_MruNode  cnode = first;
134
135
136        do
137        {
138          if ( cnode == node )
139            goto Ok;
140          cnode = cnode->next;
141
142        } while ( cnode != first );
143
144        fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" );
145        exit( 2 );
146      Ok:
147      }
148#endif
149
150    prev = node->prev;
151    next = node->next;
152
153    prev->next = next;
154    next->prev = prev;
155
156    if ( node == next )
157    {
158      FT_ASSERT( first == node );
159      FT_ASSERT( prev  == node );
160
161      *plist = NULL;
162    }
163    else if ( node == first )
164      *plist = next;
165  }
166
167
168  FT_LOCAL_DEF( void )
169  FTC_MruList_Init( FTC_MruList       list,
170                    FTC_MruListClass  clazz,
171                    FT_UInt           max_nodes,
172                    FT_Pointer        data,
173                    FT_Memory         memory )
174  {
175    list->num_nodes = 0;
176    list->max_nodes = max_nodes;
177    list->nodes     = NULL;
178    list->clazz     = *clazz;
179    list->data      = data;
180    list->memory    = memory;
181  }
182
183
184  FT_LOCAL_DEF( void )
185  FTC_MruList_Reset( FTC_MruList  list )
186  {
187    while ( list->nodes )
188      FTC_MruList_Remove( list, list->nodes );
189
190    FT_ASSERT( list->num_nodes == 0 );
191  }
192
193
194  FT_LOCAL_DEF( void )
195  FTC_MruList_Done( FTC_MruList  list )
196  {
197    FTC_MruList_Reset( list );
198  }
199
200
201#ifndef FTC_INLINE
202  FT_LOCAL_DEF( FTC_MruNode )
203  FTC_MruList_Find( FTC_MruList  list,
204                    FT_Pointer   key )
205  {
206    FTC_MruNode_CompareFunc  compare = list->clazz.node_compare;
207    FTC_MruNode              first, node;
208
209
210    first = list->nodes;
211    node  = NULL;
212
213    if ( first )
214    {
215      node = first;
216      do
217      {
218        if ( compare( node, key ) )
219        {
220          if ( node != first )
221            FTC_MruNode_Up( &list->nodes, node );
222
223          return node;
224        }
225
226        node = node->next;
227
228      } while ( node != first);
229    }
230
231    return NULL;
232  }
233#endif
234
235  FT_LOCAL_DEF( FT_Error )
236  FTC_MruList_New( FTC_MruList   list,
237                   FT_Pointer    key,
238                   FTC_MruNode  *anode )
239  {
240    FT_Error     error;
241    FTC_MruNode  node = NULL;
242    FT_Memory    memory = list->memory;
243
244
245    if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
246    {
247      node = list->nodes->prev;
248
249      FT_ASSERT( node );
250
251      if ( list->clazz.node_reset )
252      {
253        FTC_MruNode_Up( &list->nodes, node );
254
255        error = list->clazz.node_reset( node, key, list->data );
256        if ( !error )
257          goto Exit;
258      }
259
260      FTC_MruNode_Remove( &list->nodes, node );
261      list->num_nodes--;
262
263      if ( list->clazz.node_done )
264        list->clazz.node_done( node, list->data );
265    }
266    else if ( FT_ALLOC( node, list->clazz.node_size ) )
267      goto Exit;
268
269    error = list->clazz.node_init( node, key, list->data );
270    if ( error )
271      goto Fail;
272
273    FTC_MruNode_Prepend( &list->nodes, node );
274    list->num_nodes++;
275
276  Exit:
277    *anode = node;
278    return error;
279
280  Fail:
281    if ( list->clazz.node_done )
282      list->clazz.node_done( node, list->data );
283
284    FT_FREE( node );
285    goto Exit;
286  }
287
288
289#ifndef FTC_INLINE
290  FT_LOCAL_DEF( FT_Error )
291  FTC_MruList_Lookup( FTC_MruList   list,
292                      FT_Pointer    key,
293                      FTC_MruNode  *anode )
294  {
295    FTC_MruNode  node;
296
297
298    node = FTC_MruList_Find( list, key );
299    if ( node == NULL )
300      return FTC_MruList_New( list, key, anode );
301
302    *anode = node;
303    return 0;
304  }
305#endif /* FTC_INLINE */
306
307  FT_LOCAL_DEF( void )
308  FTC_MruList_Remove( FTC_MruList  list,
309                      FTC_MruNode  node )
310  {
311    FTC_MruNode_Remove( &list->nodes, node );
312    list->num_nodes--;
313
314    {
315      FT_Memory  memory = list->memory;
316
317
318      if ( list->clazz.node_done )
319        list->clazz.node_done( node, list->data );
320
321      FT_FREE( node );
322    }
323  }
324
325
326  FT_LOCAL_DEF( void )
327  FTC_MruList_RemoveSelection( FTC_MruList              list,
328                               FTC_MruNode_CompareFunc  selection,
329                               FT_Pointer               key )
330  {
331    FTC_MruNode  first, node, next;
332
333
334    first = list->nodes;
335    while ( first && ( selection == NULL || selection( first, key ) ) )
336    {
337      FTC_MruList_Remove( list, first );
338      first = list->nodes;
339    }
340
341    if ( first )
342    {
343      node = first->next;
344      while ( node != first )
345      {
346        next = node->next;
347
348        if ( selection( node, key ) )
349          FTC_MruList_Remove( list, node );
350
351        node = next;
352      }
353    }
354  }
355
356
357/* END */