774
854
if (priv->current_mtime_cache_parent)
775
855
g_object_unref (priv->current_mtime_cache_parent);
777
if (priv->directories) {
778
g_list_foreach (priv->directories, (GFunc) directory_data_unref, NULL);
779
g_list_free (priv->directories);
857
tracker_priority_queue_foreach (priv->directories,
858
(GFunc) directory_data_unref,
860
tracker_priority_queue_unref (priv->directories);
782
862
if (priv->config_directories) {
783
863
g_list_foreach (priv->config_directories, (GFunc) directory_data_unref, NULL);
784
864
g_list_free (priv->config_directories);
787
g_queue_foreach (priv->crawled_directories, (GFunc) crawled_directory_data_free, NULL);
788
g_queue_free (priv->crawled_directories);
867
tracker_priority_queue_foreach (priv->crawled_directories,
868
(GFunc) crawled_directory_data_free,
870
tracker_priority_queue_unref (priv->crawled_directories);
790
872
/* Cancel every pending task */
791
tracker_processing_pool_foreach (priv->processing_pool,
792
processing_pool_cancel_foreach,
794
tracker_processing_pool_free (priv->processing_pool);
796
g_queue_foreach (priv->items_moved, (GFunc) item_moved_data_free, NULL);
797
g_queue_free (priv->items_moved);
799
g_queue_foreach (priv->items_deleted, (GFunc) g_object_unref, NULL);
800
g_queue_free (priv->items_deleted);
802
g_queue_foreach (priv->items_updated, (GFunc) g_object_unref, NULL);
803
g_queue_free (priv->items_updated);
805
g_queue_foreach (priv->items_created, (GFunc) g_object_unref, NULL);
806
g_queue_free (priv->items_created);
873
tracker_task_pool_foreach (priv->task_pool,
874
task_pool_cancel_foreach,
876
g_object_unref (priv->task_pool);
877
g_list_free (priv->extraction_tasks);
879
g_object_unref (priv->writeback_pool);
881
if (priv->sparql_buffer) {
882
g_object_unref (priv->sparql_buffer);
885
tracker_priority_queue_foreach (priv->items_moved,
886
(GFunc) item_moved_data_free,
888
tracker_priority_queue_unref (priv->items_moved);
890
tracker_priority_queue_foreach (priv->items_deleted,
891
(GFunc) g_object_unref,
893
tracker_priority_queue_unref (priv->items_deleted);
895
tracker_priority_queue_foreach (priv->items_updated,
896
(GFunc) g_object_unref,
898
tracker_priority_queue_unref (priv->items_updated);
900
tracker_priority_queue_foreach (priv->items_created,
901
(GFunc) g_object_unref,
903
tracker_priority_queue_unref (priv->items_created);
905
tracker_priority_queue_foreach (priv->items_writeback,
906
(GFunc) item_writeback_data_free,
908
tracker_priority_queue_unref (priv->items_writeback);
808
910
g_list_foreach (priv->dirs_without_parent, (GFunc) g_object_unref, NULL);
809
911
g_list_free (priv->dirs_without_parent);
844
946
g_value_get_double (value));
846
948
case PROP_WAIT_POOL_LIMIT:
847
tracker_processing_pool_set_wait_limit (fs->priv->processing_pool,
848
g_value_get_uint (value));
949
tracker_task_pool_set_limit (fs->priv->task_pool,
950
g_value_get_uint (value));
850
952
case PROP_READY_POOL_LIMIT:
851
tracker_processing_pool_set_ready_limit (fs->priv->processing_pool,
852
g_value_get_uint (value));
854
case PROP_N_REQUESTS_POOL_LIMIT:
855
tracker_processing_pool_set_n_requests_limit (fs->priv->processing_pool,
856
g_value_get_uint (value));
953
fs->priv->sparql_buffer_limit = g_value_get_uint (value);
955
if (fs->priv->sparql_buffer) {
956
tracker_task_pool_set_limit (TRACKER_TASK_POOL (fs->priv->sparql_buffer),
957
fs->priv->sparql_buffer_limit);
858
960
case PROP_MTIME_CHECKING:
859
961
fs->priv->mtime_checking = g_value_get_boolean (value);
1126
1220
g_slice_free (ItemMovedData, data);
1130
processing_pool_task_finished_cb (TrackerProcessingTask *task,
1132
const GError *error)
1223
static ItemWritebackData *
1224
item_writeback_data_new (GFile *file,
1228
ItemWritebackData *data;
1230
data = g_slice_new (ItemWritebackData);
1232
data->file = g_object_ref (file);
1233
data->results = g_ptr_array_ref (results);
1234
data->rdf_types = g_strdupv (rdf_types);
1235
data->cancellable = g_cancellable_new ();
1236
data->notified = FALSE;
1242
item_writeback_data_free (ItemWritebackData *data)
1244
g_object_unref (data->file);
1245
g_ptr_array_unref (data->results);
1246
g_strfreev (data->rdf_types);
1247
g_object_unref (data->cancellable);
1248
g_slice_free (ItemWritebackData, data);
1252
sparql_buffer_task_finished_cb (GObject *object,
1253
GAsyncResult *result,
1134
1256
TrackerMinerFS *fs;
1135
1257
TrackerMinerFSPrivate *priv;
1259
GError *error = NULL;
1137
1261
fs = user_data;
1138
1262
priv = fs->priv;
1264
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
1141
1266
g_critical ("Could not execute sparql: %s", error->message);
1142
1267
priv->total_files_notified_error++;
1144
if (fs->priv->current_iri_cache_parent) {
1148
task_file = tracker_processing_task_get_file (task);
1150
/* Note: parent may be NULL if the file represents
1151
* the root directory of the file system (applies to
1152
* .gvfs mounts also!) */
1153
parent = g_file_get_parent (task_file);
1156
if (g_file_equal (parent, fs->priv->current_iri_cache_parent) &&
1157
g_hash_table_lookup (fs->priv->iri_cache, task_file) == NULL) {
1158
/* Item is processed, add an empty element for the processed GFile,
1159
* in case it is again processed before the cache expires
1161
g_hash_table_insert (fs->priv->iri_cache,
1162
g_object_ref (task_file),
1166
g_object_unref (parent);
1268
g_error_free (error);
1269
} else if (fs->priv->current_iri_cache_parent) {
1273
task = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1274
task_file = tracker_task_get_file (task);
1276
/* Note: parent may be NULL if the file represents
1277
* the root directory of the file system (applies to
1278
* .gvfs mounts also!) */
1279
parent = g_file_get_parent (task_file);
1282
if (g_file_equal (parent, fs->priv->current_iri_cache_parent) &&
1283
g_hash_table_lookup (fs->priv->iri_cache, task_file) == NULL) {
1284
/* Item is processed, add an empty element for the processed GFile,
1285
* in case it is again processed before the cache expires
1287
g_hash_table_insert (fs->priv->iri_cache,
1288
g_object_ref (task_file),
1292
g_object_unref (parent);
1553
1699
g_hash_table_remove (fs->priv->iri_cache, file);
1703
iri_cache_check_update (TrackerMinerFS *fs,
1708
parent = g_file_get_parent (file);
1711
if (!fs->priv->current_iri_cache_parent ||
1712
!g_file_equal (parent, fs->priv->current_iri_cache_parent)) {
1713
/* Cache the URN for the new current parent, processing
1714
* order guarantees that all contents for a folder are
1715
* inspected together, and that the parent folder info
1716
* is already in tracker-store. So this should only
1717
* happen on folder switch.
1719
if (fs->priv->current_iri_cache_parent)
1720
g_object_unref (fs->priv->current_iri_cache_parent);
1722
g_free (fs->priv->current_iri_cache_parent_urn);
1724
fs->priv->current_iri_cache_parent = g_object_ref (parent);
1726
if (!item_query_exists (fs,
1729
&fs->priv->current_iri_cache_parent_urn,
1731
fs->priv->current_iri_cache_parent_urn = NULL;
1734
ensure_iri_cache (fs, file);
1737
g_object_unref (parent);
1556
1741
static UpdateProcessingTaskContext *
1557
1742
update_processing_task_context_new (TrackerMiner *miner,
1558
1744
const gchar *urn,
1559
1745
const gchar *parent_urn,
1560
1746
GCancellable *cancellable,
1658
item_add_or_update_cb (TrackerMinerFS *fs,
1659
TrackerProcessingTask *task,
1660
const GError *error)
1846
item_add_or_update_cb (TrackerMinerFS *fs,
1847
TrackerTask *extraction_task,
1848
const GError *error)
1662
1850
UpdateProcessingTaskContext *ctxt;
1851
TrackerTask *sparql_task;
1663
1852
GFile *task_file;
1666
ctxt = tracker_processing_task_get_context (task);
1667
task_file = tracker_processing_task_get_file (task);
1855
ctxt = tracker_task_get_data (extraction_task);
1856
task_file = tracker_task_get_file (extraction_task);
1668
1857
uri = g_file_get_uri (task_file);
1671
TrackerProcessingTask *first_item_task;
1673
first_item_task = tracker_processing_pool_get_last_wait (fs->priv->processing_pool);
1860
TrackerTask *first_item_task = NULL;
1863
first_task = g_list_last (fs->priv->extraction_tasks);
1866
first_item_task = first_task->data;
1675
1869
/* Perhaps this is too specific to TrackerMinerFiles, if the extractor
1676
1870
* is choking on some file, the miner will get a timeout for all files
1770
1969
g_debug ("Creating new item '%s'", uri);
1773
tracker_processing_task_set_sparql (task, ctxt->builder);
1972
sparql_task = tracker_sparql_task_new_with_sparql (task_file, ctxt->builder);
1776
/* If push_ready_task() returns FALSE, it means the actual db update was delayed,
1777
* and in this case we need to setup queue handlers again */
1778
if (!tracker_processing_pool_push_ready_task (fs->priv->processing_pool,
1780
processing_pool_task_finished_cb,
1975
tracker_sparql_buffer_push (fs->priv->sparql_buffer,
1978
sparql_buffer_task_finished_cb,
1981
if (!tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) {
1782
1982
item_queue_handlers_set_up (fs);
1985
tracker_task_unref (extraction_task);
1788
1990
static gboolean
1789
1991
item_add_or_update (TrackerMinerFS *fs,
1792
1995
TrackerMinerFSPrivate *priv;
1793
1996
TrackerSparqlBuilder *sparql;
1794
1997
GCancellable *cancellable;
1795
1998
gboolean retval;
1796
TrackerProcessingTask *task;
1798
2000
const gchar *urn;
1799
const gchar *parent_urn = NULL;
1800
2001
UpdateProcessingTaskContext *ctxt;
1802
2003
priv = fs->priv;
1806
2007
sparql = tracker_sparql_builder_new_update ();
1807
2008
g_object_ref (file);
1809
parent = g_file_get_parent (file);
1812
if (!fs->priv->current_iri_cache_parent ||
1813
!g_file_equal (parent, fs->priv->current_iri_cache_parent)) {
1814
/* Cache the URN for the new current parent, processing
1815
* order guarantees that all contents for a folder are
1816
* inspected together, and that the parent folder info
1817
* is already in tracker-store. So this should only
1818
* happen on folder switch.
1820
if (fs->priv->current_iri_cache_parent)
1821
g_object_unref (fs->priv->current_iri_cache_parent);
1823
g_free (fs->priv->current_iri_cache_parent_urn);
1825
fs->priv->current_iri_cache_parent = g_object_ref (parent);
1827
if (!item_query_exists (fs,
1830
&fs->priv->current_iri_cache_parent_urn,
1832
fs->priv->current_iri_cache_parent_urn = NULL;
1835
ensure_iri_cache (fs, file);
1838
parent_urn = fs->priv->current_iri_cache_parent_urn;
1839
g_object_unref (parent);
1842
2010
/* Force a direct URN query if not found in the cache. This is to handle
1843
2011
* situations where an application inserted items in the store after we
1844
2012
* updated the cache, or without a proper nfo:belongsToContainer */
1847
2015
/* Create task and add it to the pool as a WAIT task (we need to extract
1848
2016
* the file metadata and such) */
1849
task = tracker_processing_task_new (file);
1850
2017
ctxt = update_processing_task_context_new (TRACKER_MINER (fs),
2020
fs->priv->current_iri_cache_parent_urn,
1855
tracker_processing_task_set_context (task,
1857
(GFreeFunc) update_processing_task_context_free);
1858
tracker_processing_pool_push_wait_task (priv->processing_pool, task);
2023
task = tracker_task_new (file, ctxt,
2024
(GDestroyNotify) update_processing_task_context_free);
2025
tracker_task_pool_add (priv->task_pool, task);
2026
priv->extraction_tasks = g_list_prepend (priv->extraction_tasks, task);
1860
2028
if (do_process_file (fs, task)) {
1861
2029
fs->priv->total_files_processed++;
1863
if (tracker_processing_pool_wait_limit_reached (priv->processing_pool)) {
2031
if (tracker_task_pool_limit_reached (priv->task_pool)) {
1864
2032
retval = FALSE;
1908
2076
/* Add new task to processing pool */
1909
task = tracker_processing_task_new (file);
1910
tracker_processing_task_set_bulk_operation (task,
1912
" ?f tracker:available true "
1914
TRACKER_BULK_MATCH_EQUALS |
1915
TRACKER_BULK_MATCH_CHILDREN);
2077
task = tracker_sparql_task_new_bulk (file,
2079
" ?f tracker:available true "
2081
TRACKER_BULK_MATCH_EQUALS |
2082
TRACKER_BULK_MATCH_CHILDREN);
1917
/* If push_ready_task() returns FALSE, it means the actual db update was delayed,
1918
* and in this case we need to setup queue handlers again */
1919
if (!tracker_processing_pool_push_ready_task (fs->priv->processing_pool,
1921
processing_pool_task_finished_cb,
1923
item_queue_handlers_set_up (fs);
2084
tracker_sparql_buffer_push (fs->priv->sparql_buffer,
2087
sparql_buffer_task_finished_cb,
1927
2091
* Actually remove all resources. This operation is the one which may take
1931
2095
/* Add new task to processing pool */
1932
task = tracker_processing_task_new (file);
1933
tracker_processing_task_set_bulk_operation (task,
1935
" ?f a rdfs:Resource "
1937
TRACKER_BULK_MATCH_EQUALS |
1938
TRACKER_BULK_MATCH_CHILDREN);
1940
/* If push_ready_task() returns FALSE, it means the actual db update was delayed,
1941
* and in this case we need to setup queue handlers again */
1942
if (!tracker_processing_pool_push_ready_task (fs->priv->processing_pool,
1944
processing_pool_task_finished_cb,
2096
task = tracker_sparql_task_new_bulk (file,
2098
" ?f a rdfs:Resource "
2100
TRACKER_BULK_MATCH_EQUALS |
2101
TRACKER_BULK_MATCH_CHILDREN);
2103
tracker_sparql_buffer_push (fs->priv->sparql_buffer,
2106
sparql_buffer_task_finished_cb,
2109
if (!tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) {
1946
2110
item_queue_handlers_set_up (fs);
2280
2445
g_main_loop_unref (move_data.main_loop);
2282
2447
/* Add new task to processing pool */
2283
task = tracker_processing_task_new (file);
2284
/* Note that set_sparql_string() takes ownership of the passed string */
2285
tracker_processing_task_set_sparql_string (task,
2286
g_string_free (sparql, FALSE));
2287
/* If push_ready_task() returns FALSE, it means the actual db update was delayed,
2288
* and in this case we need to setup queue handlers again */
2289
if (!tracker_processing_pool_push_ready_task (fs->priv->processing_pool,
2291
processing_pool_task_finished_cb,
2448
task = tracker_sparql_task_new_take_sparql_str (file,
2449
g_string_free (sparql,
2451
tracker_sparql_buffer_push (fs->priv->sparql_buffer,
2454
sparql_buffer_task_finished_cb,
2457
if (!tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) {
2293
2458
item_queue_handlers_set_up (fs);
2428
2601
static QueueState
2429
2602
item_queue_get_next_file (TrackerMinerFS *fs,
2431
GFile **source_file)
2604
GFile **source_file,
2433
2607
ItemMovedData *data;
2608
ItemWritebackData *wdata;
2434
2609
GFile *queue_file;
2436
/* Deleted items first */
2437
queue_file = g_queue_pop_head (fs->priv->items_deleted);
2612
/* Writeback items first */
2613
wdata = tracker_priority_queue_pop (fs->priv->items_writeback,
2616
gboolean processing;
2618
*file = g_object_ref (wdata->file);
2619
*source_file = NULL;
2620
*priority_out = priority;
2622
trace_eq_pop_head ("WRITEBACK", wdata->file);
2624
g_signal_emit (fs, signals[WRITEBACK_FILE], 0,
2634
task = tracker_task_new (wdata->file, wdata,
2635
(GDestroyNotify) item_writeback_data_free);
2636
tracker_task_pool_add (fs->priv->writeback_pool, task);
2638
return QUEUE_WRITEBACK;
2640
item_writeback_data_free (wdata);
2644
/* Deleted items second */
2645
queue_file = tracker_priority_queue_pop (fs->priv->items_deleted,
2438
2647
if (queue_file) {
2439
2648
*source_file = NULL;
2642
2871
guint items_to_process = 0;
2643
2872
guint items_total = 0;
2645
items_to_process += g_queue_get_length (fs->priv->items_deleted);
2646
items_to_process += g_queue_get_length (fs->priv->items_created);
2647
items_to_process += g_queue_get_length (fs->priv->items_updated);
2648
items_to_process += g_queue_get_length (fs->priv->items_moved);
2874
items_to_process += tracker_priority_queue_get_length (fs->priv->items_deleted);
2875
items_to_process += tracker_priority_queue_get_length (fs->priv->items_created);
2876
items_to_process += tracker_priority_queue_get_length (fs->priv->items_updated);
2877
items_to_process += tracker_priority_queue_get_length (fs->priv->items_moved);
2878
items_to_process += tracker_priority_queue_get_length (fs->priv->items_writeback);
2650
g_queue_foreach (fs->priv->crawled_directories,
2651
(GFunc) get_tree_progress_foreach,
2880
tracker_priority_queue_foreach (fs->priv->crawled_directories,
2881
(GFunc) get_tree_progress_foreach,
2654
2884
items_total += fs->priv->total_directories_found;
2655
2885
items_total += fs->priv->total_files_found;
2822
3057
keep_processing = item_remove (fs, file);
2824
3059
case QUEUE_CREATED:
2825
/* Check existence before processing, if requested to do so. */
3060
/* If the item is a directory which was found during crawling, we need
3061
* to check existence before processing */
2826
3062
if (g_object_get_qdata (G_OBJECT (file),
2827
fs->priv->quark_check_existence)) {
2828
/* Clear the qdata */
2829
g_object_set_qdata (G_OBJECT (file),
2830
fs->priv->quark_check_existence,
2831
GINT_TO_POINTER (FALSE));
2833
/* Avoid adding items that already exist, when processing
2834
* a CREATED task (as those generated when crawling) */
2835
if (!item_query_exists (fs, file, FALSE, NULL, NULL)) {
2836
keep_processing = item_add_or_update (fs, file);
3063
fs->priv->quark_directory_found_crawling) &&
3064
item_query_exists (fs, file, FALSE, NULL, NULL)) {
2840
3065
/* If already in store, skip processing the CREATED task */
2841
3066
keep_processing = TRUE;
2844
3069
/* Else, fall down and treat as QUEUE_UPDATED */
2845
3070
case QUEUE_UPDATED:
2846
keep_processing = item_add_or_update (fs, file);
3071
parent = g_file_get_parent (file);
3072
iri_cache_check_update (fs, file);
3075
fs->priv->current_iri_cache_parent_urn ||
3076
file_is_crawl_directory (fs, file)) {
3077
keep_processing = item_add_or_update (fs, file, priority);
3079
TrackerPriorityQueue *item_queue;
3082
uri = g_file_get_uri (parent);
3083
g_message ("Parent '%s' not indexed yet", uri);
3086
if (queue == QUEUE_CREATED) {
3087
item_queue = fs->priv->items_created;
3089
item_queue = fs->priv->items_updated;
3092
/* Parent isn't indexed yet, reinsert the task into the queue,
3093
* but forcily prepended by its parent so its indexing is
3094
* ensured, tasks are inserted at a higher priority so they
3095
* are processed promptly anyway.
3097
tracker_priority_queue_add (item_queue,
3098
g_object_ref (parent),
3101
tracker_priority_queue_add (item_queue,
3102
g_object_ref (file),
3104
keep_processing = TRUE;
3108
g_object_unref (parent);
2848
3112
case QUEUE_IGNORE_NEXT_UPDATE:
2849
3113
keep_processing = item_ignore_next_update (fs, file, source_file);
3115
case QUEUE_WRITEBACK:
3116
/* Nothing to do here */
3117
keep_processing = TRUE;
2852
3120
g_assert_not_reached ();
3265
3535
return should_change_index_for_file (fs, file);
3269
compare_files (gconstpointer a,
3272
if (g_file_equal (G_FILE (a), G_FILE (b))) {
3280
compare_moved_files (gconstpointer a,
3539
moved_files_equal (gconstpointer a,
3283
3542
const ItemMovedData *data = a;
3284
3543
GFile *file = G_FILE (b);
3286
3545
/* Compare with dest file */
3287
if (g_file_equal (data->file, file)) {
3294
/* Checks previous created/updated/deleted/moved queues for
3546
return g_file_equal (data->file, file);
3550
writeback_files_equal (gconstpointer a,
3553
const ItemWritebackData *data = a;
3554
GFile *file = G_FILE (b);
3556
/* Compare with dest file */
3557
return g_file_equal (data->file, file);
3561
remove_writeback_task (TrackerMinerFS *fs,
3565
ItemWritebackData *data;
3567
task = tracker_task_pool_find (fs->priv->writeback_pool, file);
3573
data = tracker_task_get_data (task);
3575
if (data->notified) {
3576
tracker_task_pool_remove (fs->priv->writeback_pool, task);
3577
tracker_task_unref (task);
3585
cancel_writeback_task (TrackerMinerFS *fs,
3590
task = tracker_task_pool_find (fs->priv->writeback_pool, file);
3593
ItemWritebackData *data;
3595
data = tracker_task_get_data (task);
3596
g_cancellable_cancel (data->cancellable);
3597
tracker_task_pool_remove (fs->priv->writeback_pool, task);
3598
tracker_task_unref (task);
3602
/* Checks previous created/updated/deleted/moved/writeback queues for
3295
3603
* monitor events. Returns TRUE if the item should still
3296
3604
* be added to the queue.
3298
3606
static gboolean
3299
3607
check_item_queues (TrackerMinerFS *fs,
3612
ItemMovedData *move_data;
3306
3614
if (!fs->priv->been_crawled) {
3307
3615
/* Only do this after initial crawling, so
3321
3646
case QUEUE_UPDATED:
3322
3647
/* No further updates after a previous created/updated event */
3323
if (g_queue_find_custom (fs->priv->items_created, file, compare_files) ||
3324
g_queue_find_custom (fs->priv->items_updated, file, compare_files)) {
3648
if (tracker_priority_queue_find (fs->priv->items_created, NULL,
3649
(GEqualFunc) g_file_equal, file) ||
3650
tracker_priority_queue_find (fs->priv->items_updated, NULL,
3651
(GEqualFunc) g_file_equal, file)) {
3325
3652
g_debug (" Found previous unhandled CREATED/UPDATED event");
3655
case QUEUE_WRITEBACK:
3656
/* No consecutive writebacks for the same file */
3657
if (tracker_priority_queue_find (fs->priv->items_writeback, NULL,
3658
writeback_files_equal, file)) {
3659
g_debug (" Found previous unhandled WRITEBACK event");
3330
3664
case QUEUE_DELETED:
3331
elem = g_queue_find_custom (fs->priv->items_updated, file, compare_files);
3665
if (tracker_task_pool_find (fs->priv->writeback_pool, file)) {
3666
/* Cancel writeback operations on a deleted file */
3667
cancel_writeback_task (fs, file);
3334
/* Remove all previous updates */
3670
/* Remove all previous updates */
3671
if (tracker_priority_queue_foreach_remove (fs->priv->items_updated,
3672
(GEqualFunc) g_file_equal,
3674
(GDestroyNotify) g_object_unref)) {
3335
3675
g_debug (" Deleting previous unhandled UPDATED event");
3336
g_object_unref (elem->data);
3337
g_queue_delete_link (fs->priv->items_updated, elem);
3340
elem = g_queue_find_custom (fs->priv->items_created, file, compare_files);
3343
/* Created event still in the queue,
3678
if (tracker_priority_queue_foreach_remove (fs->priv->items_updated,
3679
(GEqualFunc) g_file_equal,
3681
(GDestroyNotify) g_object_unref)) {
3682
/* Created event was still in the queue,
3344
3683
* remove it and ignore the current event
3346
3685
g_debug (" Found matching unhandled CREATED event, removing file altogether");
3347
g_object_unref (elem->data);
3348
g_queue_delete_link (fs->priv->items_created, elem);
3353
3690
case QUEUE_MOVED:
3691
if (tracker_task_pool_find (fs->priv->writeback_pool, file)) {
3692
/* If the origin file is also being written back,
3693
* cancel it as this is an external operation.
3695
cancel_writeback_task (fs, file);
3354
3698
/* Kill any events on other_file (The dest one), since it will be rewritten anyway */
3355
elem = g_queue_find_custom (fs->priv->items_created, other_file, compare_files);
3699
if (tracker_priority_queue_foreach_remove (fs->priv->items_created,
3700
(GEqualFunc) g_file_equal,
3702
(GDestroyNotify) g_object_unref)) {
3358
3703
g_debug (" Removing previous unhandled CREATED event for dest file, will be rewritten anyway");
3359
g_object_unref (elem->data);
3360
g_queue_delete_link (fs->priv->items_created, elem);
3363
elem = g_queue_find_custom (fs->priv->items_updated, other_file, compare_files);
3706
if (tracker_priority_queue_foreach_remove (fs->priv->items_updated,
3707
(GEqualFunc) g_file_equal,
3709
(GDestroyNotify) g_object_unref)) {
3366
3710
g_debug (" Removing previous unhandled UPDATED event for dest file, will be rewritten anyway");
3367
g_object_unref (elem->data);
3368
g_queue_delete_link (fs->priv->items_updated, elem);
3371
3713
/* Now check file (Origin one) */
3372
elem = g_queue_find_custom (fs->priv->items_created, file, compare_files);
3375
/* If source file was created, replace the
3376
* GFile there, we assume all posterior updates
3714
if (tracker_priority_queue_foreach_remove (fs->priv->items_created,
3715
(GEqualFunc) g_file_equal,
3717
(GDestroyNotify) g_object_unref)) {
3718
/* If source file was created, replace it with
3719
* a create event for the destination file, and
3720
* discard this event.
3722
* We assume all posterior updates
3377
3723
* have been merged together previously by this
3378
3724
* same function.
3380
3726
g_debug (" Found matching unhandled CREATED event "
3381
3727
"for source file, merging both events together");
3382
g_object_unref (elem->data);
3383
elem->data = g_object_ref (other_file);
3728
tracker_priority_queue_add (fs->priv->items_created,
3729
g_object_ref (other_file),
3730
G_PRIORITY_DEFAULT);
3388
elem = g_queue_find_custom (fs->priv->items_moved, file, compare_moved_files);
3391
ItemMovedData *data = elem->data;
3735
move_data = tracker_priority_queue_find (fs->priv->items_moved, NULL,
3736
(GEqualFunc) moved_files_equal, file);
3393
3738
/* Origin file was the dest of a previous
3394
3739
* move operation, merge these together.
3396
3741
g_debug (" Source file is the destination of a previous "
3397
3742
"unhandled MOVED event, merging both events together");
3398
g_object_unref (data->file);
3399
data->file = g_object_ref (other_file);
3743
g_object_unref (move_data->file);
3744
move_data->file = g_object_ref (other_file);
3633
3995
/* Source file was not stored, check dest file as new */
3634
3996
if (!is_directory ||
3635
3997
!should_recurse_for_directory (fs, other_file)) {
3636
trace_eq_push_tail ("CREATED", other_file, "On move monitor event");
3637
g_queue_push_tail (fs->priv->items_created,
3638
g_object_ref (other_file));
3998
if (check_item_queues (fs, QUEUE_CREATED, other_file, NULL)) {
3999
trace_eq_push_tail ("CREATED", other_file, "On move monitor event");
4000
tracker_priority_queue_add (fs->priv->items_created,
4001
g_object_ref (other_file),
4002
G_PRIORITY_DEFAULT);
3640
item_queue_handlers_set_up (fs);
4004
item_queue_handlers_set_up (fs);
3642
tracker_miner_fs_directory_add_internal (fs, other_file);
4007
tracker_miner_fs_directory_add_internal (fs, other_file,
4008
G_PRIORITY_DEFAULT);
3645
4011
/* Else, do nothing else */
3789
4158
* -mtime_checking is TRUE.
3791
4160
if (fs->priv->been_crawled || fs->priv->mtime_checking) {
3792
/* Set quark so that before trying to add the item we first
3793
* check for its existence. */
4161
/* Set quark to identify item found during crawling */
3794
4162
g_object_set_qdata (G_OBJECT (parent),
3795
fs->priv->quark_check_existence,
4163
fs->priv->quark_directory_found_crawling,
3796
4164
GINT_TO_POINTER (TRUE));
3798
4166
/* Before adding the monitor, start notifying the store
3799
4167
* about the new directory, so that if any file event comes
3800
4168
* afterwards, the directory is already in store. */
3801
4169
trace_eq_push_tail ("CREATED", parent, "while crawling directory, parent");
3802
g_queue_push_tail (fs->priv->items_created,
3803
g_object_ref (parent));
4170
tracker_priority_queue_add (fs->priv->items_created,
4171
g_object_ref (parent),
4172
G_PRIORITY_DEFAULT);
3804
4173
item_queue_handlers_set_up (fs);
3806
4175
/* As we already added here, specify that it shouldn't be added
4328
dirs = fs->priv->crawled_directories->head;
4331
CrawledDirectoryData *data = dirs->data;
4336
if (g_file_equal (file, data->tree->data) ||
4337
g_file_has_prefix (file, data->tree->data)) {
4338
crawled_directory_data_free (data);
4339
g_queue_delete_link (priv->crawled_directories, link);
4721
tracker_priority_queue_foreach_remove (fs->priv->crawled_directories,
4722
(GEqualFunc) crawled_directory_contains_file,
4724
(GDestroyNotify) crawled_directory_data_free);
4344
4726
/* Remove anything contained in the removed directory
4345
4727
* from all relevant processing queues.
4347
check_files_removal (priv->items_updated, file);
4348
check_files_removal (priv->items_created, file);
4729
tracker_priority_queue_foreach_remove (priv->items_updated,
4730
(GEqualFunc) file_equal_or_descendant,
4732
(GDestroyNotify) g_object_unref);
4733
tracker_priority_queue_foreach_remove (priv->items_created,
4734
(GEqualFunc) file_equal_or_descendant,
4736
(GDestroyNotify) g_object_unref);
4350
4738
g_debug (" Removed files at %f\n", g_timer_elapsed (timer, NULL));
4831
* tracker_miner_fs_check_file_with_priority:
4832
* @fs: a #TrackerMinerFS
4833
* @file: #GFile for the file to check
4834
* @priority: the priority of the check task
4835
* @check_parents: whether to check parents and eligibility or not
4837
* Tells the filesystem miner to check and index a file at
4838
* a given priority, this file must be part of the usual
4839
* crawling directories of #TrackerMinerFS. See
4840
* tracker_miner_fs_directory_add().
4845
tracker_miner_fs_check_file_with_priority (TrackerMinerFS *fs,
4848
gboolean check_parents)
4850
gboolean should_process = TRUE;
4853
g_return_if_fail (TRACKER_IS_MINER_FS (fs));
4854
g_return_if_fail (G_IS_FILE (file));
4856
if (check_parents) {
4857
should_process = should_check_file (fs, file, FALSE);
4860
path = g_file_get_path (file);
4862
g_debug ("%s:'%s' (FILE) (requested by application)",
4863
should_process ? "Found " : "Ignored",
4866
if (should_process) {
4867
if (check_parents && !check_file_parents (fs, file)) {
4871
trace_eq_push_tail ("UPDATED", file, "Requested by application");
4872
tracker_priority_queue_add (fs->priv->items_updated,
4873
g_object_ref (file),
4876
item_queue_handlers_set_up (fs);
4884
* tracker_miner_fs_writeback_file:
4885
* @fs: a #TrackerMinerFS
4886
* @file: #GFile for the file to check
4887
* @rdf_types: A #GStrv with rdf types
4888
* @results: A array of results from the preparation query
4890
* Tells the filesystem miner to writeback a file.
4895
tracker_miner_fs_writeback_file (TrackerMinerFS *fs,
4901
ItemWritebackData *data;
4903
g_return_if_fail (TRACKER_IS_MINER_FS (fs));
4904
g_return_if_fail (G_IS_FILE (file));
4906
path = g_file_get_path (file);
4908
g_debug ("Performing write-back:'%s' (requested by application)", path);
4910
trace_eq_push_tail ("WRITEBACK", file, "Requested by application");
4912
data = item_writeback_data_new (file, rdf_types, results);
4913
tracker_priority_queue_add (fs->priv->items_writeback, data,
4914
G_PRIORITY_DEFAULT);
4916
item_queue_handlers_set_up (fs);
4922
* tracker_miner_fs_writeback_notify:
4923
* @fs: a #TrackerMinerFS
4925
* @error: a #GError with the error that happened during processing, or %NULL.
4927
* Notifies @fs that all writing back on @file has been finished, if any error
4928
* happened during file data processing, it should be passed in @error, else
4929
* that parameter will contain %NULL to reflect success.
4934
tracker_miner_fs_writeback_notify (TrackerMinerFS *fs,
4936
const GError *error)
4940
g_return_if_fail (TRACKER_IS_MINER_FS (fs));
4941
g_return_if_fail (G_IS_FILE (file));
4943
fs->priv->total_files_notified++;
4945
task = tracker_task_pool_find (fs->priv->writeback_pool, file);
4950
uri = g_file_get_uri (file);
4951
g_critical ("%s has notified that file '%s' has been written back, "
4952
"but that file was not in the task pool. "
4953
"This is an implementation error, please ensure that "
4954
"tracker_miner_fs_writeback_notify() is called on the same "
4955
"GFile that is passed in ::writeback-file, and that this"
4956
"signal didn't return FALSE for it",
4957
G_OBJECT_TYPE_NAME (fs), uri);
4960
g_warning ("Writeback operation failed: %s", error->message);
4962
/* We don't expect any further monitor
4963
* events on the original file.
4965
tracker_task_pool_remove (fs->priv->writeback_pool, task);
4966
tracker_task_unref (task);
4968
item_queue_handlers_set_up (fs);
4970
ItemWritebackData *data;
4972
data = tracker_task_get_data (task);
4973
data->notified = TRUE;
4976
/* Check monitor_item_updated_cb() for the remainder of this notify,
4977
* as the last event happening on the written back file would be an
4978
* UPDATED event caused by the changes on the cloned file, followed
4979
* by a MOVE onto the original file, so the delayed update happens
4980
* on the destination file.
4440
4985
* tracker_miner_fs_check_file:
4441
4986
* @fs: a #TrackerMinerFS
4442
4987
* @file: #GFile for the file to check