In the implementations of svn_fs_get_mergeinfo, make sure that the
[svn.git] / notes / entries-caching
blobe49262ab7257b25cc73c6ef2d609034300a76b25
2                     "I have a cunning plan"
4                              or
6              Entries Caching in the Access Batons
10 0. Preamble
11    --------
13 Issue 749 provides some history.  The access batons now cache the
14 parsed entries file, as repeatedly reading, parsing and writing the
15 file proved to be a bottleneck.
18 1. Caching Interface
19    -----------------
21 The basic functions to retrieve entries are svn_wc_entries_read and
22 svn_wc_entry.  The function svn_wc__entries_write is used to update
23 the entries file on disk.  The function svn_wc__entry_modify is
24 implemented in terms of entries_read and entries_write.
26 1.1 Write Caching Overview
28 An overview of the update process.
30    1. Lock the directory
31    2. Read the entries file and cache in memory
32    3. Start the wc update
33       3.1  Start a directory update
34          3.1.1 Start file update
35             3.1.1.1 Write a log file specific to this item
36          3.1.3 Finish file update
37       3.2. Finish directory update
38       3.3. Run log files
39          3.3.1. Log file commands modify entries in memory
40       3.4  Finish log files
41       3.5. Flush entries to disk
42       3.6. Remove log files
43    4. Finish update
44    5. Unlock directory
46 Each directory update may contain multiple file updates so when the
47 directory update is complete there may be multiple log files.  While
48 the log files are being run the entries modifications are cached in
49 memory and written once when the log files are complete.  The reason
50 for accumulating multiple log files is that flushing the entries to
51 disk involves writing the entire entries file, if it were done after
52 each file then the total amount of entries data written would grow
53 exponentially during a checkout.
56 2. Interface Enhancements
57    ----------------------
59 2.1 Entries Interface
61 A lot of the entries interface has remained unchanged since the
62 pre-caching days, and it shows.  Of particular concern is the
63 svn_wc_entries_read function, as this provides access to the raw data
64 within the cache.  If the application carelessly modifies the data
65 things may go wrong.  I would like to remove this function.
67 One use of svn_wc_entries_read is in svn_wc__entry_modify, this is
68 "within the entries code" and so is not a problem.
70 Of the other uses of svn_wc_entries_read the most common is where the
71 application wants to iterate over all the entries in a directory. I
72 would like to see an interface something like
74   typedef struct svn_wc_entry_iterator_t svn_wc_entry_iterator_t;
76   svn_wc_entry_iterator_t *
77   svn_wc_entry_first(svn_wc_adm_access_t *adm_access,
78                      apr_pool_t *pool);
80   svn_wc_entry_iterator_t *
81   svn_wc_entry_next(svn_wc_entry_iterator_t *entry_iterator);
83   const svn_wc_entry_t *
84   svn_wc_entry_iterator_entry(svn_wc_entry_iterator_t *entry_iterator);
86 Note that this provides only const access to the entries, the
87 application cannot modify the cached data.  All modifications would go
88 through svn_wc__entry_modify, and the access batons could keep track
89 of whether modifications have been made and not yet written to disk.
91 The other uses of svn_wc_entries_read tend to extract a single entry.
92 I hope these can be converted to use svn_wc_entry.  One slight problem
93 is the use of svn_wc_entries_read to intentionally extract a
94 directory's entry from its parent.  This is done because that's where
95 the "deleted" state is stored.  I think the entry returned by
96 svn_wc_entry could contain this state.  Why doesn't it?  I don't know,
97 possibly it's an accident, or possibly it's intentional as in the past
98 parsing two entries files would have been expensive.
100 2.2 Access Baton Interface
102 I would also like to modify the access baton interface.  At present
103 the open function detects and skips missing directories when opening a
104 directory hierarchy.  I would like to record this information in the
105 access baton set, and modify the retrieve functions to include an
106 svn_boolean_t* parameter that gets set TRUE when a request for a
107 missing directory is made.  The advantage of doing this is that the
108 application could avoid making svn_io_check_path and svn_wc_check_wc
109 calls when the access baton already has the information.  The function
110 prop_path_internal looks like a good candidate for this optimisation.
113 3. Access Baton Sets
114    -----------------
116 Each access baton represents a directory.  Access batons can associate
117 together in sets.  Given an access baton in a set, it possible to
118 retrieve any other access baton in the set.  When an access baton in a
119 set is closed, all other access batons in the set that represent
120 subdirectories are also closed.  The set is implemented as a hash
121 table "owned" by the one baton in any set, but shared by all batons in
122 the set.
124 At present in the code, access batons are opened in a parent->child
125 order.  This works well with the shared hash being owned by the first
126 baton in each set.  There is code to detect if closing a baton will
127 destroy the hash while other batons are using it, as far as I know it
128 doesn't currently trigger.  If it turns out that this needs to be
129 supported it should be possible to transfer the hash information to
130 another baton.
133 4. Access Baton Conversion
134    -----------------------
136 Given a function
137   svn_error_t *foo (const char *path);
138 if PATH is always a directory then the change that gets made is usually
139   svn_error_t *foo (svn_wc_adm_access_t *adm_access);
140 Within foo, the original const char* can be obtained using
141   const char *svn_wc_adm_access_path(svn_wc_adm_access_t *adm_access);
143 The above case sometimes occurs as
144   svn_error_t *foo(const char *name, const char *dir);
145 where NAME is a single path component, and DIR is a directory. Conversion
146 is again simply in this case
147   svn_error_t *foo (const char *name, svn_wc_adm_access_t *adm_access);
149 The more difficult case is
150   svn_error_t *foo (const char *path);
151 where PATH can be a file or a directory.  This occurs a lot in the
152 current code. In the long term these may get converted to
153   svn_error_t *foo (const char *name, svn_wc_adm_access_t *adm_access);
154 where NAME is a single path component.  However this involves more
155 changes to the code calling foo than are strictly necessary, so
156 initially they get converted to
157   svn_error_t *foo (const char *path, svn_wc_adm_access_t *adm_access);
158 where PATH is passed unchanged and an additional access baton is
159 passed.  This interface is less than ideal, since there is duplicate
160 information in the path and baton, but since it involves fewer changes
161 in the calling code it makes a reasonable intermediate step.
164 5. Logging
165    -------
167 As well as caching the other problem that needs to be addressed is the
168 issue of logging.  Modifications to the working copy are supposed to
169 use the log file mechanism to ensure that multiple changes that need
170 to be atomic cannot be partially completed.  If the individual changes
171 that may need to be logged are all forced to use an access baton, then
172 the access baton may be able to identify when the log file mechanism
173 should be used.  Combine this with an access baton state that tracks
174 whether a log file is being run and we may be able to automatically
175 identify those places that are failing to use the log file mechanism.
178 6. Status
179    ------
181 Entries caching has been implemented.
183 The interface changes (section 2) have not been started.
185 The access baton conversion is complete in so far as passing batons is
186 concerned.  The path->name signature changes (section 4) have not been
187 made.
189 Automatic detection of failure to use a log file (section 5) has not
190 been started.