Subversion Repositories Filer-Free

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
63 gdshaw@RISCPKG.ORG 1
// This file is part of the free Filer module for RISC OS.
2
// Copyright  2007 Graham Shaw.
3
// Redistribution and modification are permitted under the terms of the
4
// GNU General Public License (version 2 or any later version).
5
 
6
#ifndef FILER_PATHNAME_TABLE
7
#define FILER_PATHNAME_TABLE
8
 
9
class filer_window;
10
 
11
/** A table for mapping pathnames to filer windows.
12
 * For speed, pathnames are hashed before they are indexed.
13
 * @note At present there is no mechanism for preventing hash collisions:
14
 *  all matching filer windows are refreshed.  This is considered acceptable.
15
 * @warning The layout of this class must match the offsets given
16
 *  in the file "_pathname_table.s".
17
 */
18
class pathname_table
19
{
20
public:
21
        /** A type to represent a number of index entries. */
22
        typedef unsigned int size_type;
23
 
24
        /** A class to represent an entry in the table.
25
         * @warning The layout of this structure must match the offsets given
26
         *  in the file "_pathname_table.s".
27
         */
28
        struct node
29
        {
30
                /** The next node in the refresh queue.
31
                 * If this is the last node in the queue, or if this is not a
32
                 * member of a queue, then the value of this field is undefined
33
                 */
34
                node* next;
35
 
36
                /** The refresh pending flag.
37
                 * True if a refresh is pending for this node (and therefore,
38
                 * it has been added to the refresh queue), otherwise false.
39
                 */
40
                int refresh;
41
 
42
                /** The filer window associated with this node. */
43
                filer_window* window;
44
 
45
                /** The index entry occupied by this node.
46
                 * This may change when other nodes are added or removed from
47
                 * the index.
48
                 */
49
                int index;
50
        };
51
private:
52
        /** The number of nodes in the pathname table. */
53
        volatile size_type _size;
54
 
55
        /** The capacity of the index. */
56
        size_type _capacity;
57
 
58
        /** The index (pathname hash array).
59
         * This is a ordered array of pathname hashes.  It must remain ordered
60
         * (for all indices less than _size) at all times.
61
         */
62
        volatile int* _index_data;
63
 
64
        /** The index (node table). */
65
        volatile node** _index_nodes;
66
 
67
        /** The tail of the refresh queue. */
68
        volatile node* _tail;
69
 
70
        /** The pollword to be set if there are windows in need of a refresh. */
71
        int* _pollword;
72
 
73
        /** A buffer for use by the upcall handler.
74
         * When the upcall handler is notified on an operation on a filehandle
75
         * it converts that filehandle into a pathname.  For this is needs a
76
         * buffer to hold the pathname.  Allocating from the RMA from within
77
         * the handler would be highly undesirable, therefore a suitable buffer
78
         * is permanently allocated.
79
         */
80
        char _pathname_buffer[256];
81
 
82
        /** The head of the refresh queue.
83
         * Although this member is not referenced directly by the upcall
84
         * handler, it can be altered by the handler indirectly through _tail
85
         * (which may point to _head).  For this reason it is marked as
86
         * volatile.
87
         */
88
        volatile node _head;
89
 
90
        /** The head of the free list. */
91
        node _free;
92
public:
93
        /** Construct pathname table.
94
         * @param pollword the pollword to be set if there are windows
95
         *  in need of a refresh
96
         */
97
        pathname_table(int* pollword);
98
 
99
        /** Destroy pathname table. */
100
        ~pathname_table();
101
 
102
        /** Reserve capacity for index to reach given size.
103
         * @param capacity the required capacity of the index
104
         */
105
        void reserve(size_type capacity);
106
 
107
        /** Insert filer window into table.
108
         * No action is taken if the filer window is already present.
109
         * @param w the filer window to be inserted
110
         */
111
        node* insert(filer_window* w);
112
 
113
        /** Remove filer window from table.
114
         * No action is taken if the filer window is not found.
115
         * @param w the filer window to be removed
116
         */
117
        void erase(node* n);
118
 
119
        /** Find filer window given pathname.
120
         * @param pathname the pathname for which to search
121
         * @return the corresponding filer window, or 0 if not found
122
         */
123
        filer_window* find(const char* pathname);
124
 
125
        /** Refresh all filer windows for which a refresh is necessary. */
126
        void refresh();
127
};
128
 
129
/** Find pathname in table.
130
 * @param table the pathname table
131
 * @param hash the hash of the pathname to be found
132
 * @param the index into the table of the first match, or table->_size
133
 *  if not found
134
 */
135
extern "C"
136
unsigned int pathname_find(pathname_table* table,unsigned int hash);
137
 
138
#endif