Change Flora License Version
[platform/core/uifw/e17.git] / doc / cache.txt
1 As part of the .eap to .desktop conversion, raster wants me to redo the
2 relevant caching to suit.  He has made many "eap caching needs
3 fixing" noises in the recent past, so maybe a fresh start is needed
4 at this point.  
5
6 This is a discussion and design document.  Major parts of it where sent
7 to the devel list but got no response.  Raster said to put it in here,
8 and keep it up to date with whatever information and design is relevant.
9
10
11 The problem -
12
13 It's really the E_App structure as defined in e_apps.h that may need
14 caching, no matter what their source.  I say "no matter what their
15 source" because at the moment the sources are .eap files and .desktop
16 files, and at some unspecified date in the future .eap files might go
17 away.  I say "may need caching" because this is a fresh start, do they
18 really need caching?
19
20 To answer that last question we need to look at all the places that use
21 E_Apps and check to see if those uses are performance critical.  Then
22 we need to see how much time it takes to load an E_App from it's source.
23
24 Grepping through the source code shows that E_App is used in the ibar,
25 engage, and mbar modules, plus in E itself.  Devilhorns tells me that
26 mbar will be replaced, so I will ignore that for now.  HandyAndE tells
27 me that the stand alone version of engage is deprecated, so I can
28 ignore that.  Both ibar and engage essentially do the same things with
29 E_App, so I'll speak about those in generic terms.  I'll also try to
30 avoid spending time fully groking all the code that uses E_Apps, as I
31 have some time pressure here.  That's why I'm thinking out loud, if I
32 miss something, other devs will point it out.
33
34 Interesting that neither entangle, nor the stand alone eapp_edit came up
35 in the grep results.  There may be other things that deal with
36 application icons in their own way.  I'll ignore them for now.  I know
37 raster will say "engage entangle and such ar not part of corr e, ignre
38 them".  Entangle and the stand alone eapp_edit are now obsolete, as they
39 where not included in the .desktop update.
40
41 Ibar and engage both display a handful of application icons, allow the
42 user to click on those icons to start the application.  Ibar runs a
43 "starting application" animation, and engage keeps track of open
44 windows that belong to all applications, but tries to keep the open
45 window icons next to the application icon if it has one for that
46 application.  I don't know if ibar uses the freedesktop.org startup
47 notification spec, some other method, or just runs the animation for an
48 arbitrary time.  Either way, there are three operations in these
49 modules that use E_Apps - show the icon, start the application, and
50 match newly created windows with the E_App.
51
52 E also needs to do those three operations, and more.  Menus, winlist,
53 pager, exebuf, and borders all need to show the icon.  Menus and exebuf
54 need to start the application.  When a window is opened, it needs to be
55 matched to it's E_App to show it's icon and other things.  Exebuf needs
56 to search through all the E_Apps looking for matches to the partially
57 typed in command.  EFM needs to show an icon for any .eap or .desktop it
58 is currently displaying, maybe needs to run the application.  The
59 built in eap editor needs to read, display, and save all the
60 application icon information.
61
62 These operations fall into two distinct categories - dealing with one
63 E_App at a time, or searching through all E_Apps with arbitrary search
64 criteria.  One at a time is often done in user time (the user only
65 operates one icon at a time) so caching is not so important there.
66 Searching through all E_Apps is an expensive operation that should be
67 optimised as much as possible.  Note that I count the showing of menus
68 as the later category, as the user may want to quickly access many sub
69 menus full of E_Apps.
70
71 Since the source of the image data used for the icon can be something
72 that needs time to decode, at the times when lots of icons are being
73 used at once (exebuf and menus mostly) we probably want that image data
74 cached for speed as well.  The searching through all E_Apps can occur
75 on data that is part of the original file that is the source, so an in
76 memory search will be a lot faster than any file searching.
77
78 So the problem is - as fast as possible search through all the E_Apps,
79 no matter what their source, and give access to all the information
80 they have ,including image data.  Since this is useful in the "one at a
81 time" category, might as well use the same method there to.
82
83
84 The issues with possible solutions -
85
86 An in memory cache of all E_App information is needed.  Since the
87 information that could be used to search this cache can be quite
88 arbitrary, hashes and other such structures may not be useful.  On the
89 other hand, some sort of index mechanism may be useful for the most
90 common searches, and those that need to be quickest.
91
92 Lets try to come up with some numbers.  The eap torture test involves
93 over two thousand .eaps, and that's from a full install of SuSE 9.3
94 Pro.  Certain distros have just as many applications, or more, and they
95 are growing all the time.  120x120 pixels is probably the largest
96 commonly used icon size, 32 bits per pixel to include the alpha
97 channel.  I have seen .desktop files up to 25 KB in size, but that
98 includes all the translations for name, comment, and keywords,
99 something that is not currently stored in E_App.  A much more common
100 size is 2 - 4 KB, but that still mostly is for the name translations.
101 Note, .desktop files only include the name of the icon, not the image
102 data itself.  I use the .desktop files for this part of the discussion
103 because they include all the non image data that is typically in an
104 E_App.  1 KB is probably maximum storage requirement for non image,
105 single translation E_App data.  That could be a maximum of 56 KB per
106 E_App, and possibly 100 MB for the entire cache including image data.
107 Ouch, no wonder raster suggested mmaping the cache file.
108
109 Note, this is a likely maximum for those people that install two
110 thousand applications and like really big icons.  I have over two
111 thousand applications installed, and I like the icons in engage to zoom
112 out really big.  B-)  Typical users will require a much smaller amount
113 of data.
114
115 The original caching strategy uses multiple caches, on a per directory
116 basis, but still has a single cache for the all directory, the one with
117 all the .eaps in it.  raster has mentioned that a single cache might be
118 a better solution.  With .desktop files scattered all over the place, a
119 single cache is more desirable for searching purposes.
120
121 This does raise some interesting issues.  While .eap files have in the
122 past been per user, the majority of .desktop files are likely to be
123 system files, mostly unchanging, but with new ones added whenever new
124 software is installed.  The user can create their own, and override
125 system ones.  There is also the translations to deal with.  Do we
126 include only one translation in the cache?  Do we have a system cache
127 and per user caches that allow overrides?  Do we really need image data
128 in the cache?  Although the freedesktop.org spec says that the user
129 chooses a single icon size, in practise the various things that render
130 icons render them at different sizes.
131
132 There is the cache update strategy to consider.  The current one causes
133 problems.  Raster has thought about changing to no auto update, but with
134 a manually triggered update.  I would prefer automatic updates that
135 work smoothly and without great pauses in the operation of the wm, as
136 that gives the users less to complain about.  Maybe we can make use of
137 the thumb nailing stuff?
138
139 Answers to these questions will help choose a caching mechanism.
140
141
142 -----------------------------------------------------------------------
143
144 ecore_desktop_paths
145
146 USED BY:
147      All of the ecore_desktop code.
148 WHEN:
149      At startup.  They hardly ever change.
150 ISSUES:
151     The use of GNOME and KDE apps to figure out some of the paths. 
152     They are curently commented out, and guesses are made.
153 SOLUTION:
154     Go with the guesses, run the apps later to correct the guesses.
155     Cache the results to disk.
156
157 -----------------------------------------------------------------------
158
159 ecore_desktop_menu
160
161 USED BY:
162     "Applications" menu and "Applications" config dialog.
163 WHEN:
164     The menus are parsed at first startup, then manually by the dialog.
165 ISSUES:
166     When new applications are installed, will need to update.
167 SOLUTION:
168     Parse them during idle time, maybe as a separate process.  Monitor
169     relevant directories. ~/.e/e/applications/menu/all is the results
170     cached to disk.
171
172 -----------------------------------------------------------------------
173
174 icon themes
175
176 USED BY:
177     The icon theme config dialog.
178 WHEN:
179     When the icon theme config dialog is started.
180 ISSUES:
181     The actual icon theme currently in use is a small amount of info that
182     can always be in ram, and is quick to get at startup or theme change.
183     It's the complete list of themes that are currently installed that can 
184     take ages to find.  The list itself should also be small.
185 SOLUTION:
186     Find them during idle time, and finish the job async when the dialog
187     is started.  Monitor the icon paths for the installation of new
188     themes.  Keep them all in a hash.
189
190 -----------------------------------------------------------------------
191
192 icons
193
194 USED BY:
195     Whenever an E_App is displayed and others.
196 WHEN:
197     On demand.
198 ISSUES:
199     Combined .edj and FDO searching. FDO searching can take a long time.
200     Things that display lots of icons wont want to wait for all those 
201     complex searches.  Searching for icons that don't exist is what
202     takes the longest, as the FDO algo means we have to look through all
203     the directories, in this theme, and the next theme.
204 SOLUTION:
205     e_app_icon_add() should be used everywhere, and it should register a 
206     rectangle for use by the icon.  The caller then shows an empty icon.
207     A thumbnailing style process then does all the searching, and does 
208     the fm2 bouncy icon thing when the icon is found.  raster forbids 
209     this method.
210
211     The results of the search should be cached somewhere on disk for 
212     future reference.  That needs to be nuked when the user changes 
213     icon theme.  Changing the icon theme currently does not update all 
214     displayed icons, it just does a restart like wm theme changing does. 
215     The X-Enlightenment-IconPath field of the .desktop file could be
216     used for the on disk cache.  X-Enlightenment-Icon-Theme and
217     X-Enlightenment-Icon-TimeStamp can be used to determine if the icon
218     path stored on disk is out of date, or in a different theme.  An
219     idle task can go through all the .desktops in
220     ~/.e/e/applications/all and check if the icons need updating.  The
221     spec allows caching of dirs, and we can monitor just the top level
222     icon theme directory.
223
224 -----------------------------------------------------------------------
225
226 .desktop files
227
228 USED BY:
229     E_Apps and others.
230 WHEN:
231     Whenever the E_App needs to be read from disk.
232 ISSUES:
233     Currently a fairly simple in memory hash of them is kept.  Since 
234     each Ecore_Desktop holds a hash of the fields, this can be 
235     expensive in memory.  Also, we would like a pre parsed binary on
236     disk cache for the sheer speed.  ~/.e/e/applications/all is a 
237     directory with all of them that are for E_Apps, some are just links 
238     to system files. 
239 SOLUTION:
240     Remove after implementing the E_App cache then see if these still
241     needs caching.  Note that the menu generation probably reads the
242     .desktop files twice each.
243
244 -----------------------------------------------------------------------
245
246 .order files
247 USED BY:
248     Menus, bars, startup, restart.
249 WHEN:
250     When displaying the menu or bar.  At startup and restart.  When
251     editing them.
252 ISSUES:
253 SOLUTION:
254
255 -----------------------------------------------------------------------
256
257 E_Apps
258
259 USED BY:
260     Menus, bars, borders, exebuf, lots of other places.
261 WHEN:
262     Currently all read in at startup time.  Should change this to an 
263     idle time task.  Still need to read in them all near startup time 
264     though.  We need all of them for searching.
265
266     a_actions searches for filename, name, generic, and exe to find an
267     app to execute.  Updates the most recently used list.
268
269     e_border searches for border and pid to find the border icon.  The
270     border search involves searching all E_Apps for win_* and exe that
271     match the app in the border.  The pid search involves searching all
272     instances of all E_Apps, looking for a matching pid.  Both searches
273     update the most recently used list.  None of this is needed for
274     remember stuff.
275
276     e_exebuf searches/lists all apps and most recently used apps based
277     on a partially typed in string.  It globs name, exe, generic, and
278     comment.  When actually listing the matches, it searches for exe. 
279     When showing an icon for the current match, it searches exe, name,
280     then generic.  Updates the most recently used list.
281
282     e_zone searches for exe to find a matching E_App when it is
283     executing things.  Updates the most recently used list.
284
285     e_int_config_apps shows a sorted list of all apps.
286
287     Everything else loads E_Apps by file name or directory name.  Some
288     have .order files.
289
290 ISSUES:
291     The current eap caching code is not up to scratch, and the .desktop 
292     conversion didn't help.  It does hide some other bugs though, so that 
293     needs to be cleaned up first.
294
295     How this all hangs together is complex.
296
297     Evas_List *_e_app_repositories;
298         Only contains ~/.e/e/applications/all for now.
299
300     E_App *_e_apps_all = ~/.e/e/applications/all
301         Currently has all the E_Apps as subbapps, but only used as if it was a single E_App.
302         On the other hand, this is scanned at startup time, so is used to preload the caches.
303         
304     _e_apps_list = Most recently used list / all apps list.
305
306     E_App members -
307
308     E_App *parent; /* the parent e_app node */
309         e_apps.c internal
310         This is in a directory, the parent is the E_App for that directory.
311
312     Evas_List *subapps; /* if this a directory, a list of more E_App's */
313         e_apps.c internal except for _e_startup and _e_int_menus_apps_scan
314         This will be a directory with a .order file, subapps points to the content E_Apps.
315
316     Evas_List *references; /* If this app is in a main repository, this would
317                               be a list to other eapp pointing to this */
318         e_apps.c internal
319         E_Apps in a repository are copied before use, this points to those copies.
320
321     E_App *orig; /* if this is a copy, point to the original */
322         e_apps.c internal except for _e_border_menu_cb_icon_edit
323         E_Apps in a repository are copied before use, this points to the original.
324
325     Evas_List *instances; /* a list of all the exe handles for executions */
326         e_apps.c internal except for e_zone_exec
327         Tracks E_Apps that are currently running.
328
329     Ecore_File_Monitor *monitor; /* Check for changes and files */
330         e_apps.c internal
331         Only E_Apps that are directories are monitored.
332
333
334 SOLUTION:
335     Start by putting all filenames in ~/.e/e/applications/all in a hash
336     with "empty" E_Apps.  Fill the "empty" E_Apps during idle time, also
337     as needed.  Everytime a new .desktop file is created, add it to the
338     hash and put it in the directory.
339
340     The most recently used list can be built from whatever gets used, it
341     could actually speed things up if it does not contain everything, as
342     it is usually a linear search.  On the other hand, we could reuse
343     the subapps of _e_apps_all as this list, since it already exists,
344     and it doesn't care what order its subapps are in.
345
346     Executing an app can probably afford to use a slow search.  Border
347     icons could make use of bouncy icon thumbnailing.  e_int_config_apps
348     can just show ~/.e/e/applications/all, but e_fm will need to know to
349     sort based on visible name.  e_exebuf can also use bouncy icon
350     thumbnailing, but may need more speedups for its globbing.
351
352     Later we shall see if an on disk copy is needed.
353
354 ------------------------------------------------------------------------------
355 comments on cache doc:
356
357    1. ignore caching of image data - evas already does that. just provide
358       file paths and "keys" if inside .edj/eap/eet files. don't duplicate
359       image data or do anything "smart" as it will invariably end up less
360       smart that the existing evas cache :) so don't worry about icons and
361       their pixels - just the file paths/keys
362    2. instead of "in memory" let's try a new idea. lets put it in a flat
363       mmap'ed file (not eet). let's not make it architecture dependent
364       (write any integers in a fixed byte order) and make it all offset
365       based. fill the file with strings and indexes and fast search indexes
366       etc. 1 big flat file for the whole cache.. the eap structs themselves
367       are "in memory" and allocated but all strings and "content" are pointed
368       to this mmaped file - map and unmap this file whenever needed (need to
369       add calls that implicitly map it when you want to access eap struct
370       contents and then unmap when done - refcount) and on map check the
371       header of the file for some "modification count) and keep the last mod
372       count value - if they don't match re-evaluate all internal tabels in
373       the map file. re-evaluate all pointers in eap structs. always try and
374       map the file to the same mem address (remember it and try map TO that
375       addr so you don't need to do address fixups). if you can't map to there
376       map to unspecified address (let mmap choose) and now keep trying to
377       map to this addr from now on. if the addr changes or the mmap file
378       changes all eap files need a fixup of their str pointers done.
379       so now you have a e_app_use() and e_app_unuse() thatg basically makes
380       sure the apps map file is mappeed after a use and unmapped after an
381       unuse (when refcount goes to 0 for the maps file - maybe with a
382       timeout to avoid map thrashing).
383       the advantage of all this is most of the time e is not accessing eapp
384       data - it just has references TO them so during this time no memory
385       is consumed by the data and no kernel mappings. we should bring mem
386       use down to a tiny fraction.
387       this is a quick braindump... so it may need more discussion. nb - this
388       is just a bug flat dump for all ".desktop files" - hash it for fast
389       lookup - have fast search hash indexes for lookup by exe, name, class
390       etc. other cache files for menu structures etc. would implicitly
391       reference data in this big fat cache.
392    3. on any change of .desktop files on the system or by users - rewrite the
393       whole cache and re-fix pointers etc. - this shouldn't happen often.
394    4. same mmap setup for lookups of icon name in .desktop -> fully resolved
395       path based on icon themes and inheritance. if the themes change then
396       re-evaluate this cache.
397    5. .order files and menu structs can just live in the same cache.
398    6. all eaps can be quickyl created at startup from an all apps cache that
399       referenced the desktop content cache file as above. putting it into
400       an idel taks means on addition of new eaps all window icons need
401       re-evaluation as to all eap instances in ibar etc. etc. - makes life
402       more complex (for now). maybe simpler on that front and better cache
403       will work well here.
404    7. eap instances are created as you lanich apps - no need to cache or
405       worry about these - the search by exe, win name/class etc. are what
406       we need to worry about :)
407    8. the above should mean no need to fill in eaps in idlers - map the
408       "big fat desktop cache" that contains everything - icon paths, labels
409       exe strings etc. when needed - fox up all pointers in eapp structs
410       if the contents or base address ever change - unmap when refcount
411       goes to 0 (with a timeout to avoid thrashing).