Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/LibSVM/Cache.cs @ 2257

Last change on this file since 2257 was 1819, checked in by mkommend, 16 years ago

created new project for LibSVM source files (ticket #619)

File size: 5.2 KB
Line 
1/*
2 * SVM.NET Library
3 * Copyright (C) 2008 Matthew Johnson
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20using System;
21
22namespace SVM
23{
24    internal class Cache
25    {
26        private int _count;
27        private long _size;
28
29        private sealed class head_t
30        {
31            public head_t(Cache enclosingInstance)
32            {
33                _enclosingInstance = enclosingInstance;
34            }
35            private Cache _enclosingInstance;
36            public Cache EnclosingInstance
37            {
38                get
39                {
40                    return _enclosingInstance;
41                }
42            }
43            internal head_t prev, next; // a cicular list
44            internal float[] data;
45            internal int len; // data[0,len) is cached in this entry
46        }
47
48        private head_t[] head;
49        private head_t lru_head;
50
51        internal Cache(int count, long size)
52        {
53            _count = count;
54            _size = size;
55            head = new head_t[_count];
56            for (int i = 0; i < _count; i++)
57                head[i] = new head_t(this);
58            _size /= 4;
59            _size -= _count * (16 / 4); // sizeof(head_t) == 16
60            lru_head = new head_t(this);
61            lru_head.next = lru_head.prev = lru_head;
62        }
63
64        private void lru_delete(head_t h)
65        {
66            // delete from current location
67            h.prev.next = h.next;
68            h.next.prev = h.prev;
69        }
70
71        private void lru_insert(head_t h)
72        {
73            // insert to last position
74            h.next = lru_head;
75            h.prev = lru_head.prev;
76            h.prev.next = h;
77            h.next.prev = h;
78        }
79
80        // request data [0,len)
81        // return some position p where [p,len) need to be filled
82        // (p >= len if nothing needs to be filled)
83        // java: simulate pointer using single-element array
84        internal virtual int get_data(int index, float[][] data, int len)
85        {
86            head_t h = head[index];
87            if (h.len > 0)
88                lru_delete(h);
89            int more = len - h.len;
90
91            if (more > 0)
92            {
93                // free old space
94                while (_size < more)
95                {
96                    head_t old = lru_head.next;
97                    lru_delete(old);
98                    _size += old.len;
99                    old.data = null;
100                    old.len = 0;
101                }
102
103                // allocate new space
104                float[] new_data = new float[len];
105                if (h.data != null)
106                    Array.Copy(h.data, 0, new_data, 0, h.len);
107                h.data = new_data;
108                _size -= more;
109                do
110                {
111                    int _ = h.len; h.len = len; len = _;
112                }
113                while (false);
114            }
115
116            lru_insert(h);
117            data[0] = h.data;
118            return len;
119        }
120
121        internal virtual void swap_index(int i, int j)
122        {
123            if (i == j)
124                return;
125
126            if (head[i].len > 0)
127                lru_delete(head[i]);
128            if (head[j].len > 0)
129                lru_delete(head[j]);
130            do
131            {
132                float[] _ = head[i].data; head[i].data = head[j].data; head[j].data = _;
133            }
134            while (false);
135            do
136            {
137                int _ = head[i].len; head[i].len = head[j].len; head[j].len = _;
138            }
139            while (false);
140            if (head[i].len > 0)
141                lru_insert(head[i]);
142            if (head[j].len > 0)
143                lru_insert(head[j]);
144
145            if (i > j)
146                do
147                {
148                    int _ = i; i = j; j = _;
149                }
150                while (false);
151            for (head_t h = lru_head.next; h != lru_head; h = h.next)
152            {
153                if (h.len > i)
154                {
155                    if (h.len > j)
156                        do
157                        {
158                            float _ = h.data[i]; h.data[i] = h.data[j]; h.data[j] = _;
159                        }
160                        while (false);
161                    else
162                    {
163                        // give up
164                        lru_delete(h);
165                        _size += h.len;
166                        h.data = null;
167                        h.len = 0;
168                    }
169                }
170            }
171        }
172    }
173}
Note: See TracBrowser for help on using the repository browser.