So, following the work to remove inotify and just use GIO, find attached
the list of steps we may need when getting GIO events in order to
translate them into TrackerMonitor events.

As background, GIO raw events are listed here:
http://library.gnome.org/devel/gio/stable/GFileMonitor.html#GFileMonitorEvent

And the TrackerMonitor events are just:
  - "item-created"
  - "item-updated"
  - "item-deleted"
  - "item-moved"

Note that for event translations, I considered files and directory
events in a different way internally, because different steps should be
considered in each case.

These steps should cover all cases, including the issues of getting
DELETE events for directory A when moving it from A to B (in addition to
the MOVE(A->B) event). Using a new HT for those, which is actually the
thing fully complicating the issue...

Anyway, my impression is that even if all these steps are done, the
miner-fs should process them "in the same order" as notified by
TrackerMonitor, not based on 4 different queues where delete events have
precedence (IIRC)... although then that's another issue...

Comments more than welcome, specially from Carlos and Martyn :-)

-- 
Aleksander
Assuming we have 3 different Hash Tables:

  * pre-update-file, will store only 2 types of events:
    - G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(file)
    - G_FILE_MONITOR_EVENT_CREATED(file)

  * pre-update-dir, will store only 1 type of events (Actually, this one may be
    mixed with the previous one in a single pre-update HT, but anyway):
    - G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(directory)

  * pre-delete-dir, will store only 2 types of events:
    - G_FILE_MONITOR_EVENT_DELETED(directory)
    - G_FILE_MONITOR_EVENT_MOVED(source_dir->dest_dir)


*** FILE events

<FILE_UPDATED(A)> =       (  N   * G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A) +
                             N   * G_FILE_MONITOR_EVENT_CHANGED(A) +
                           (1|0) * G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT(A)) ||
                          (  1   * G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A))

<FILE_CREATED(A)> =          1   * G_FILE_MONITOR_EVENT_CREATED(A) +
                             1   * <FILE_UPDATED(A)>
<FILE_DELETED (A)> =         1   * G_FILE_MONITOR_EVENT_DELETED(A)

<FILE_MOVED(A->B)> =         1   * G_FILE_MONITOR_EVENT_MOVED(A->B)


  - When a G_FILE_MONITOR_EVENT_CREATED(A) is received,
    -- If there is a previous G_FILE_MONITOR_EVENT_CREATED(A) event in the
       pre-update-file cache, issue warning, and leave the previous event in
       the cache.
    -- If there is a previous G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A) event in
       the pre-update-file cache, issue warning, remove the
       G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A), and add a new
       G_FILE_MONITOR_EVENT_CREATED(A) to the cache.


  - When receiving a G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A):
    -- If there is a previous G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A) in the
       pre-update-file cache, don't do anything.
    -- If there is a previous G_FILE_MONITOR_EVENT_CREATED(A) in the
       pre-update-file cache, don't do anything.
    -- If there is no previous item in the pre-update-file cache, add it.


  - When receiving a G_FILE_MONITOR_EVENT_CHANGED(A):
    -- If there is a previous G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A) in the
       pre-update-file cache, remove the event from the cache. We know that
       after a G_FILE_MONITOR_EVENT_CHANGED event, there must always be a
       G_FILE_MONITOR_EVENT_CHANGED_DONE_HINT which always ends the event. This
       will avoid cache expiration of that previous event where only attributes
       of the file were changed.
    -- If there is a previous G_FILE_MONITOR_EVENT_CREATED(A) event in the
       pre-update-file cache, don't do anything.

  - When receiving a G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT(A):
    -- First of all, check if there is a G_FILE_MONITOR_EVENT_MOVED(B->C) in the
       pre-delete-dir cache where C is a parent directory of A. In this case,
       the parent directory of A was first moved, and then A was modified (A is
       notified after the move, so A is inside C). So, first issue the
       DIRECTORY_MOVED(B->C), remove it from pre-delete-dir cache, and then keep
       on with the following steps.
    -- If there is a G_FILE_MONITOR_EVENT_MOVED(B->C) in the pre-delete-dir
       cache where B is a parent directory of A, issue a warning, then keep on
       with the following steps.
    -- If there was a G_FILE_MONITOR_EVENT_CREATED(A) in the pre-update-file
       cache, notify FILE_CREATED(A), and remove from the cache.
    -- If there was a G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A) in the
       pre-update-file cache, notify FILE_UPDATED(A), and remove from the cache.
    -- If there is no previous item in the pre-update-file cache, just notify
       directly FILE_UPDATED(A).


  - When receiving a G_FILE_MONITOR_EVENT_DELETED:
    -- First of all, check if there is a G_FILE_MONITOR_EVENT_MOVED(C->D) in the
       pre-delete-dir cache where D is a parent directory of A. In this case,
       the parent directory of A was first moved, and then A was deleted (A is
       notified after the move, so A is inside D). So, first issue the
       DIRECTORY_MOVED(C->D), remove it from pre-delete-dir cache, and then keep
       on with the following steps.
    -- If there is a G_FILE_MONITOR_EVENT_MOVED(B->C) in the pre-delete-dir
       cache where B is a parent directory of A, issue a warning, then keep on
       with the following steps.
    -- If there is any kind of event in the pre-update-file cache, remove it,
       and then notify FILE_DELETED(A).
    -- If there is no event in the pre-update-file cache, just notify
       FILE_DELETED(A).
    -- Note that in all previous cases, FILE_DELETED is notified directly, not
       added to any cache.


  - When receiving a G_FILE_MONITOR_EVENT_MOVED(A->B):
    -- First of all, check if there is a G_FILE_MONITOR_EVENT_MOVED(C->D) in the
       pre-delete-dir cache where D is either parent of A or B. In this case,
       the parent directory of A|B was first moved, and then A was moved to B.
       So, first issue the DIRECTORY_MOVED(C->D), remove it from pre-delete-dir
       cache, and then keep on with the following steps.
    -- If there is a G_FILE_MONITOR_EVENT_MOVED(B->C) in the pre-delete-dir
       cache where B is a parent directory of A, issue a warning, then keep on
       with the following steps.

    -- If there is any kind of event in the pre-update-file cache for A, notify
       it first, remove from cache, and then notify FILE_MOVED(A->B)
    -- If there is any kind of event in the pre-update-file cache for B, issue
       a warning, and then notify FILE_MOVED(A->B).
    -- If there is no event in the pre-update-file cache, just notify
       FILE_MOVED(A->B).
    -- Note that in all previous cases, FILE_MOVED is notified directly, not
       added to any cache.

  - If pre-update-file cache expires for A:
    -- First of all, check if there is a G_FILE_MONITOR_EVENT_MOVED(C->D) in the
       pre-delete-dir cache where D is parent of. In this case, the parent
       directory of A was first moved, so first issue the DIRECTORY_MOVED(C->D),
       remove it from pre-delete-dir cache, and then keep on with the following
       steps.
    -- If there is a G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED event waiting there,
       notify the FILE_UPDATED(A) event.
    -- If there is a G_FILE_MONITOR_EVENT_CREATED(A) event waiting there, notify
       the FILE_CREATED(A) event. Note that in this case, we will possibly get
       still a G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT(A) after this. This could
       happen when for example downloading a big file from the internet, where
       the final update event is quite after the original create event.


*** DIRECTORY events

<DIRECTORY_CREATED(A)>  =    1   * G_FILE_MONITOR_EVENT_CREATED(A)

<DIRECTORY_UPDATED(A)>  =    N   * G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A)

<DIRECTORY_DELETED(A)>  =    1   * G_FILE_MONITOR_EVENT_DELETED(A)

<DIRECTORY_MOVED(A->B)> = ((1|0) * G_FILE_MONITOR_EVENT_DELETED(A) +
                             1   * G_FILE_MONITOR_EVENT_MOVED(A->B) ) ||
                          (  1   * G_FILE_MONITOR_EVENT_MOVED(A->B) +
                           (1|0) * G_FILE_MONITOR_EVENT_DELETED(A))


  - When receiving a G_FILE_MONITOR_EVENT_CREATED(A) for a Directory item:
    -- If pre-delete-dir cache has a G_FILE_MONITOR_EVENT_DELETED(A), we need to
       issue first the DIRECTORY_DELETED(A) and then the DIRECTORY_CREATED(A).
       This is because the original directory may have had lots of files inside,
       while the new one is empty, so both events must be notified. Also, the
       G_FILE_MONITOR_EVENT_DELETED(A) must be removed from the pre-delete
       cache.
    -- If pre-delete-dir cache has a G_FILE_MONITOR_EVENT_MOVED(A->B), we need
       to issue first the DIRECTORY_MOVED(A->B) and then the
       DIRECTORY_CREATED(A). Also, the G_FILE_MONITOR_EVENT_MOVED(A->B) must be
       removed from the cache.
    -- In both previous cases, if pre-update-dir cache has a
       G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A) it must be removed and not
       notified, and possibly a warning issued, as there shouldn't be any 
previous
       event for A.
    -- If pre-delete-dir cache has a G_FILE_MONITOR_EVENT_MOVED(B->A), it is 
quite
       a weird situation which should not happen. Probably just issue a warning
       here and don't notify DIRECTORY_CREATED(A).
    -- If pre-update-file cache has any event for files which are in this A
       directory, issue a warning, and notify DIRECTORY_CREATED(A).
    -- Otherwise, just notify the DIRECTORY_CREATED directly.
    -- Note that in all previous cases, DIRECTORY_CREATED is notified directly,
       not added to any cache.


  - When receiving a G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A):
    -- If there is a previous event in the pre-delete-dir cache, it would be
       quite a weird situation, so issue a warning and forget about the new
       event.
    -- If there is a previous event in the pre-update-dir cache, don't do
       anything.
    -- If there is no previous event in the pre-update-dir cache, just add it.
    -- Note that these events may come in a series of events (for example, a
       chmod a+rwx generates 2 of these raw events).


  - If the G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED(A) expires in the
    pre-update-dir cache:
    -- Just notify DIRECTORY_UPDATED(A)


  - When receiving a G_FILE_MONITOR_EVENT_DELETED(A) for a Directory item:
    -- If there is any previous event in the pre-update-file cache for files
       inside directory A, notify them first, then keep on with the next steps.
       This may happen when modifying files inside the directory, and then
       moving the directory from A to B (as the G_FILE_MONITOR_EVENT_DELETED(A)
       may come first in a move operation).
    -- If there is a previous G_FILE_MONITOR_EVENT_MOVED(A->B) event in the
       pre-delete-dir cache, directly notify the previous DIRECTORY_MOVED(A->B)
       event, and forget about the DIRECTORY_DELETED(A) event.
    -- If there is a previous G_FILE_MONITOR_EVENT_MOVED(B->A) event in the
       pre-delete cache, it means we first moved the directory and then removed
       the new directory. This can actually be translated into
       DIRECTORY_DELETED(B). For example, "mv source_dir dest_dir &&
       rm -rf dest_dir" will be equivalent in terms of events to
       "rm -rf source_dir". In this case, the event for the dest dir,
       DIRECTORY_DELETED(A), shouldn't be notified.
    -- If there is a previous G_FILE_MONITOR_EVENT_DELETED(A), issue a warning
       as this is a weird situation.
    -- If there was no previous event in the pre-delete-dir cache, just add it.


  - If the G_FILE_MONITOR_EVENT_DELETED(A) expires in the pre-delete-dir cache:
    -- If there is an event in the pre-update-dir cache for A, remove it, then
       keep on with following steps.
    -- If there are events in the pre-update-file cache for files inside A,
       remove them, then keep on with following steps.
    -- Finally, notify DIRECTORY_DELETED(A).


  - When receiving a G_FILE_MONITOR_EVENT_MOVED(A->B):
    -- If there is any previous event in the pre-update-file cache for files
       inside directory A, notify them first, then keep on with the next steps.
    -- If there is any previous event in the pre-update-file cache for files
       inside directory B, issue a warning and then keep on with the next steps.
    -- If there is a previous G_FILE_MONITOR_EVENT_DELETED(A) event in the
       pre-delete-dir cache, then notify the DIRECTORY_MOVED(A->B) event and
       remove the G_FILE_MONITOR_EVENT_DELETED(A) from the cache.
    -- If there is a previous G_FILE_MONITOR_EVENT_DELETED(B) event in the
       pre-delete-dir cache, then notify the DIRECTORY_DELETED(B), and add
       the G_FILE_MONITOR_EVENT_MOVED(A->B) to the pre-delete-dir cache. For
       example in: "rm -rf dest_dir && mv source_dir dest_dir"
    -- If there is a previous G_FILE_MONITOR_EVENT_MOVED(A->B) event in the
       pre-delete-dir cache, then issue a warning as this is a weird situation.
    -- If there is a previous G_FILE_MONITOR_EVENT_MOVED(B->A) event in the
       pre-delete-dir cache, first notify the DIRECTORY_MOVED(B->A), then add
       the G_FILE_MONITOR_EVENT_MOVED(A->B) to the pre-delete-dir cache.
    -- If there is no previous event in the pre-delete-dir cache, just add it.


  - If the G_FILE_MONITOR_EVENT_MOVED(A->B) expires in the pre-delete-dir cache:
    -- If there is any previous event in the pre-update-file cache for files
       inside directory A, notify them first, then keep on with the next steps.
    -- If there is any previous event in the pre-update-file cache for files
       inside directory B, issue a warning and then keep on with the next steps.
    -- If there is an event in the pre-update-dir cache for A, notify that one
       first, then keep on with the next steps.
    -- If there is an event in the pre-update-dir cache for B, issue a warning,
       then keep on with the next steps.
    -- Finally, notify G_FILE_MONITOR_EVENT_MOVED(A->B).


As a side note, all the cases issuing warnings should never happen, but still, I
guess it may make sense to consider them because we may have missed some weird
scenario...
_______________________________________________
tracker-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/tracker-list

Reply via email to