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