| Index: src/cache/ftcmru.c
|
| diff --git a/src/cache/ftcmru.c b/src/cache/ftcmru.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dc8b4cc3970912dead7166f14110a5baeab8de64
|
| --- /dev/null
|
| +++ b/src/cache/ftcmru.c
|
| @@ -0,0 +1,357 @@
|
| +/***************************************************************************/
|
| +/* */
|
| +/* ftcmru.c */
|
| +/* */
|
| +/* FreeType MRU support (body). */
|
| +/* */
|
| +/* Copyright 2003, 2004, 2006, 2009 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 <ft2build.h>
|
| +#include FT_CACHE_H
|
| +#include "ftcmru.h"
|
| +#include FT_INTERNAL_OBJECTS_H
|
| +#include FT_INTERNAL_DEBUG_H
|
| +
|
| +#include "ftcerror.h"
|
| +
|
| +
|
| + FT_LOCAL_DEF( void )
|
| + FTC_MruNode_Prepend( FTC_MruNode *plist,
|
| + FTC_MruNode node )
|
| + {
|
| + FTC_MruNode first = *plist;
|
| +
|
| +
|
| + if ( first )
|
| + {
|
| + FTC_MruNode last = first->prev;
|
| +
|
| +
|
| +#ifdef FT_DEBUG_ERROR
|
| + {
|
| + FTC_MruNode cnode = first;
|
| +
|
| +
|
| + do
|
| + {
|
| + if ( cnode == node )
|
| + {
|
| + fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" );
|
| + exit( 2 );
|
| + }
|
| + cnode = cnode->next;
|
| +
|
| + } while ( cnode != first );
|
| + }
|
| +#endif
|
| +
|
| + first->prev = node;
|
| + last->next = node;
|
| + node->next = first;
|
| + node->prev = last;
|
| + }
|
| + else
|
| + {
|
| + node->next = node;
|
| + node->prev = node;
|
| + }
|
| + *plist = node;
|
| + }
|
| +
|
| +
|
| + FT_LOCAL_DEF( void )
|
| + FTC_MruNode_Up( FTC_MruNode *plist,
|
| + FTC_MruNode node )
|
| + {
|
| + FTC_MruNode first = *plist;
|
| +
|
| +
|
| + FT_ASSERT( first != NULL );
|
| +
|
| + if ( first != node )
|
| + {
|
| + FTC_MruNode prev, next, last;
|
| +
|
| +
|
| +#ifdef FT_DEBUG_ERROR
|
| + {
|
| + FTC_MruNode cnode = first;
|
| + do
|
| + {
|
| + if ( cnode == node )
|
| + goto Ok;
|
| + cnode = cnode->next;
|
| +
|
| + } while ( cnode != first );
|
| +
|
| + fprintf( stderr, "FTC_MruNode_Up: invalid action\n" );
|
| + exit( 2 );
|
| + Ok:
|
| + }
|
| +#endif
|
| + prev = node->prev;
|
| + next = node->next;
|
| +
|
| + prev->next = next;
|
| + next->prev = prev;
|
| +
|
| + last = first->prev;
|
| +
|
| + last->next = node;
|
| + first->prev = node;
|
| +
|
| + node->next = first;
|
| + node->prev = last;
|
| +
|
| + *plist = node;
|
| + }
|
| + }
|
| +
|
| +
|
| + FT_LOCAL_DEF( void )
|
| + FTC_MruNode_Remove( FTC_MruNode *plist,
|
| + FTC_MruNode node )
|
| + {
|
| + FTC_MruNode first = *plist;
|
| + FTC_MruNode prev, next;
|
| +
|
| +
|
| + FT_ASSERT( first != NULL );
|
| +
|
| +#ifdef FT_DEBUG_ERROR
|
| + {
|
| + FTC_MruNode cnode = first;
|
| +
|
| +
|
| + do
|
| + {
|
| + if ( cnode == node )
|
| + goto Ok;
|
| + cnode = cnode->next;
|
| +
|
| + } while ( cnode != first );
|
| +
|
| + fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" );
|
| + exit( 2 );
|
| + Ok:
|
| + }
|
| +#endif
|
| +
|
| + prev = node->prev;
|
| + next = node->next;
|
| +
|
| + prev->next = next;
|
| + next->prev = prev;
|
| +
|
| + if ( node == next )
|
| + {
|
| + FT_ASSERT( first == node );
|
| + FT_ASSERT( prev == node );
|
| +
|
| + *plist = NULL;
|
| + }
|
| + else if ( node == first )
|
| + *plist = next;
|
| + }
|
| +
|
| +
|
| + FT_LOCAL_DEF( void )
|
| + FTC_MruList_Init( FTC_MruList list,
|
| + FTC_MruListClass clazz,
|
| + FT_UInt max_nodes,
|
| + FT_Pointer data,
|
| + FT_Memory memory )
|
| + {
|
| + list->num_nodes = 0;
|
| + list->max_nodes = max_nodes;
|
| + list->nodes = NULL;
|
| + list->clazz = *clazz;
|
| + list->data = data;
|
| + list->memory = memory;
|
| + }
|
| +
|
| +
|
| + FT_LOCAL_DEF( void )
|
| + FTC_MruList_Reset( FTC_MruList list )
|
| + {
|
| + while ( list->nodes )
|
| + FTC_MruList_Remove( list, list->nodes );
|
| +
|
| + FT_ASSERT( list->num_nodes == 0 );
|
| + }
|
| +
|
| +
|
| + FT_LOCAL_DEF( void )
|
| + FTC_MruList_Done( FTC_MruList list )
|
| + {
|
| + FTC_MruList_Reset( list );
|
| + }
|
| +
|
| +
|
| +#ifndef FTC_INLINE
|
| + FT_LOCAL_DEF( FTC_MruNode )
|
| + FTC_MruList_Find( FTC_MruList list,
|
| + FT_Pointer key )
|
| + {
|
| + FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
|
| + FTC_MruNode first, node;
|
| +
|
| +
|
| + first = list->nodes;
|
| + node = NULL;
|
| +
|
| + if ( first )
|
| + {
|
| + node = first;
|
| + do
|
| + {
|
| + if ( compare( node, key ) )
|
| + {
|
| + if ( node != first )
|
| + FTC_MruNode_Up( &list->nodes, node );
|
| +
|
| + return node;
|
| + }
|
| +
|
| + node = node->next;
|
| +
|
| + } while ( node != first);
|
| + }
|
| +
|
| + return NULL;
|
| + }
|
| +#endif
|
| +
|
| + FT_LOCAL_DEF( FT_Error )
|
| + FTC_MruList_New( FTC_MruList list,
|
| + FT_Pointer key,
|
| + FTC_MruNode *anode )
|
| + {
|
| + FT_Error error;
|
| + FTC_MruNode node = NULL;
|
| + FT_Memory memory = list->memory;
|
| +
|
| +
|
| + if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
|
| + {
|
| + node = list->nodes->prev;
|
| +
|
| + FT_ASSERT( node );
|
| +
|
| + if ( list->clazz.node_reset )
|
| + {
|
| + FTC_MruNode_Up( &list->nodes, node );
|
| +
|
| + error = list->clazz.node_reset( node, key, list->data );
|
| + if ( !error )
|
| + goto Exit;
|
| + }
|
| +
|
| + FTC_MruNode_Remove( &list->nodes, node );
|
| + list->num_nodes--;
|
| +
|
| + if ( list->clazz.node_done )
|
| + list->clazz.node_done( node, list->data );
|
| + }
|
| + else if ( FT_ALLOC( node, list->clazz.node_size ) )
|
| + goto Exit;
|
| +
|
| + error = list->clazz.node_init( node, key, list->data );
|
| + if ( error )
|
| + goto Fail;
|
| +
|
| + FTC_MruNode_Prepend( &list->nodes, node );
|
| + list->num_nodes++;
|
| +
|
| + Exit:
|
| + *anode = node;
|
| + return error;
|
| +
|
| + Fail:
|
| + if ( list->clazz.node_done )
|
| + list->clazz.node_done( node, list->data );
|
| +
|
| + FT_FREE( node );
|
| + goto Exit;
|
| + }
|
| +
|
| +
|
| +#ifndef FTC_INLINE
|
| + FT_LOCAL_DEF( FT_Error )
|
| + FTC_MruList_Lookup( FTC_MruList list,
|
| + FT_Pointer key,
|
| + FTC_MruNode *anode )
|
| + {
|
| + FTC_MruNode node;
|
| +
|
| +
|
| + node = FTC_MruList_Find( list, key );
|
| + if ( node == NULL )
|
| + return FTC_MruList_New( list, key, anode );
|
| +
|
| + *anode = node;
|
| + return 0;
|
| + }
|
| +#endif /* FTC_INLINE */
|
| +
|
| + FT_LOCAL_DEF( void )
|
| + FTC_MruList_Remove( FTC_MruList list,
|
| + FTC_MruNode node )
|
| + {
|
| + FTC_MruNode_Remove( &list->nodes, node );
|
| + list->num_nodes--;
|
| +
|
| + {
|
| + FT_Memory memory = list->memory;
|
| +
|
| +
|
| + if ( list->clazz.node_done )
|
| + list->clazz.node_done( node, list->data );
|
| +
|
| + FT_FREE( node );
|
| + }
|
| + }
|
| +
|
| +
|
| + FT_LOCAL_DEF( void )
|
| + FTC_MruList_RemoveSelection( FTC_MruList list,
|
| + FTC_MruNode_CompareFunc selection,
|
| + FT_Pointer key )
|
| + {
|
| + FTC_MruNode first, node, next;
|
| +
|
| +
|
| + first = list->nodes;
|
| + while ( first && ( selection == NULL || selection( first, key ) ) )
|
| + {
|
| + FTC_MruList_Remove( list, first );
|
| + first = list->nodes;
|
| + }
|
| +
|
| + if ( first )
|
| + {
|
| + node = first->next;
|
| + while ( node != first )
|
| + {
|
| + next = node->next;
|
| +
|
| + if ( selection( node, key ) )
|
| + FTC_MruList_Remove( list, node );
|
| +
|
| + node = next;
|
| + }
|
| + }
|
| + }
|
| +
|
| +
|
| +/* END */
|
|
|