View | Details | Raw Unified | Return to bug 113869
Collapse All | Expand All

(-)beagled/FileSystemQueryable/FileSystemQueryable.cs (-39 / +73 lines)
Lines 76-82 namespace Beagle.Daemon.FileSystemQuerya Link Here
76
76
77
		//////////////////////////////////////////////////////////////////////////
77
		//////////////////////////////////////////////////////////////////////////
78
78
79
		private Hashtable pending_moves_uid_by_path = new Hashtable ();
79
		private Hashtable cached_uid_by_path = new Hashtable ();
80
80
81
		//////////////////////////////////////////////////////////////////////////
81
		//////////////////////////////////////////////////////////////////////////
82
82
Lines 324-329 namespace Beagle.Daemon.FileSystemQuerya Link Here
324
			return ToFullPath (info.Name, info.ParentId);
324
			return ToFullPath (info.Name, info.ParentId);
325
		}
325
		}
326
326
327
		private void RegisterId (string name, DirectoryModel dir, Guid id)
328
		{
329
			cached_uid_by_path [Path.Combine (dir.FullName, name)] = id;
330
		}
331
332
		private void ForgetId (string path)
333
		{
334
			cached_uid_by_path.Remove (path);
335
		}
336
337
		// This works for files.  (It probably works for directories
338
		// too, but you should use one of the more efficient means
339
		// above if you know it is a directory.)
340
		private Guid NameAndParentToId (string name, DirectoryModel dir)
341
		{
342
			string path;
343
			path = Path.Combine (dir.FullName, name);
344
345
			Guid unique_id;
346
			if (cached_uid_by_path.Contains (path))
347
				unique_id = (Guid) cached_uid_by_path [path];
348
			else
349
				unique_id = name_resolver.GetIdByNameAndParentId (name, dir.UniqueId);
350
351
			return unique_id;
352
		}
353
327
		//////////////////////////////////////////////////////////////////////////
354
		//////////////////////////////////////////////////////////////////////////
328
355
329
		//
356
		//
Lines 360-376 namespace Beagle.Daemon.FileSystemQuerya Link Here
360
			if (Debug) 
387
			if (Debug) 
361
				Logger.Log.Debug ("Expired '{0}'", expired_path);
388
				Logger.Log.Debug ("Expired '{0}'", expired_path);
362
389
363
#if false
390
			lock (dir_models_by_path)
364
			DirectoryModel dir = (DirectoryModel) dir_models_by_id [unique_id];
365
			if (dir != null && dir.WatchHandle != null)
366
				event_backend.ForgetWatch (dir.WatchHandle);
367
#endif
368
			lock (dir_models_by_id)
369
				dir_models_by_path.Remove (expired_path);
391
				dir_models_by_path.Remove (expired_path);
370
371
#if false
372
			dir_models_by_id.Remove (unique_id);
373
#endif
374
		}
392
		}
375
393
376
		public void AddDirectory (DirectoryModel parent, string name)
394
		public void AddDirectory (DirectoryModel parent, string name)
Lines 553-558 namespace Beagle.Daemon.FileSystemQuerya Link Here
553
			ActivateFileCrawling ();
571
			ActivateFileCrawling ();
554
		}
572
		}
555
573
574
		private void ForgetDirectoryRecursively (DirectoryModel dir)
575
		{
576
			foreach (DirectoryModel child in dir.Children)
577
				ForgetDirectoryRecursively (child);
578
579
			if (dir.WatchHandle != null)
580
				event_backend.ForgetWatch (dir.WatchHandle);
581
			dir_models_by_id.Remove (dir.UniqueId);
582
			// We rely on the expire event to remove it from dir_models_by_path
583
		}
584
556
		private void RemoveDirectory (DirectoryModel dir)
585
		private void RemoveDirectory (DirectoryModel dir)
557
		{
586
		{
558
			Uri uri;
587
			Uri uri;
Lines 565-570 namespace Beagle.Daemon.FileSystemQuerya Link Here
565
			// easily remap it in the PostRemoveHook.
594
			// easily remap it in the PostRemoveHook.
566
			indexable.LocalState ["RemovedUri"] = UriFu.PathToFileUri (dir.FullName);
595
			indexable.LocalState ["RemovedUri"] = UriFu.PathToFileUri (dir.FullName);
567
596
597
			// Forget watches and internal references
598
			ForgetDirectoryRecursively (dir);
599
			
568
			// Calling Remove will expire the path names,
600
			// Calling Remove will expire the path names,
569
			// so name caches will be cleaned up accordingly.
601
			// so name caches will be cleaned up accordingly.
570
			dir.Remove ();
602
			dir.Remove ();
Lines 586-591 namespace Beagle.Daemon.FileSystemQuerya Link Here
586
					    DirectoryModel new_parent, // or null if we are just renaming
618
					    DirectoryModel new_parent, // or null if we are just renaming
587
					    string new_name)
619
					    string new_name)
588
		{
620
		{
621
			if (dir == null) {
622
				Logger.Log.Warn ("Couldn't find DirectoryModel for directory moving to '{0}' in '{1}', so it was hopefully never there.",
623
						 new_name, new_parent.FullName);
624
				AddDirectory (new_parent, new_name);
625
				return;
626
			}
627
589
			if (dir.IsRoot)
628
			if (dir.IsRoot)
590
				throw new Exception ("Can't move root " + dir.FullName);
629
				throw new Exception ("Can't move root " + dir.FullName);
591
630
Lines 934-939 namespace Beagle.Daemon.FileSystemQuerya Link Here
934
			Guid unique_id;
973
			Guid unique_id;
935
			unique_id = (attr != null) ? attr.UniqueId : Guid.NewGuid ();
974
			unique_id = (attr != null) ? attr.UniqueId : Guid.NewGuid ();
936
975
976
			RegisterId (name, dir, unique_id);
977
937
			Indexable indexable;
978
			Indexable indexable;
938
			indexable = FileToIndexable (path, unique_id, dir, false);
979
			indexable = FileToIndexable (path, unique_id, dir, false);
939
980
Lines 949-958 namespace Beagle.Daemon.FileSystemQuerya Link Here
949
			// Right?
990
			// Right?
950
991
951
			Guid unique_id;
992
			Guid unique_id;
952
			unique_id = name_resolver.GetIdByNameAndParentId (name, dir.UniqueId);
993
			unique_id = NameAndParentToId (name, dir);
953
			if (unique_id == Guid.Empty) {
994
			if (unique_id == Guid.Empty) {
954
				Logger.Log.Warn ("Couldn't find unique id for '{0}' in '{1}' ({2})",
995
				Logger.Log.Warn ("Could resolve unique id of '{0}' in '{1}' for removal, it is probably already gone",
955
						 name, dir.FullName, dir.UniqueId);
996
						 name, dir.FullName);
956
				return;
997
				return;
957
			}
998
			}
958
999
Lines 965-971 namespace Beagle.Daemon.FileSystemQuerya Link Here
965
			indexable.LocalState ["RemovedUri"] = file_uri;
1006
			indexable.LocalState ["RemovedUri"] = file_uri;
966
1007
967
			Scheduler.Task task;
1008
			Scheduler.Task task;
968
			task = NewRemoveTask (uri);
1009
			task = NewAddTask (indexable);
969
			task.Priority = Scheduler.Priority.Immediate;
1010
			task.Priority = Scheduler.Priority.Immediate;
970
			ThisScheduler.Add (task);
1011
			ThisScheduler.Add (task);
971
		}
1012
		}
Lines 993-1028 namespace Beagle.Daemon.FileSystemQuerya Link Here
993
				return;
1034
				return;
994
			}
1035
			}
995
1036
996
			string old_path;
997
			old_path = Path.Combine (old_dir.FullName, old_name);
998
999
			// We need to find the file's unique id.
1037
			// We need to find the file's unique id.
1000
			// We can't look at the extended attributes w/o making
1038
			// We can't look at the extended attributes w/o making
1001
			// assumptions about whether they follow around the
1039
			// assumptions about whether they follow around the
1002
			// file (EAs) or the path (sqlite), so here is what we do:
1040
			// file (EAs) or the path (sqlite)...
1003
			// (1) Look at the pending_moves_uid_by_path hash.  This will
1004
			//     contain info about things that aren't in the index yet.
1005
			// (2) If that fails, look in the index using the name resolver.
1006
			//     to the name resolver.
1007
			
1008
			Guid unique_id;
1041
			Guid unique_id;
1009
			if (pending_moves_uid_by_path.Contains (old_path)) {
1042
			unique_id = NameAndParentToId (old_name, old_dir);
1010
				unique_id = (Guid) pending_moves_uid_by_path [old_path];
1043
			if (unique_id == Guid.Empty) {
1011
				pending_moves_uid_by_path.Remove (old_path);
1044
				// If we can't find the unique ID, we have to
1012
			} else {
1045
				// assume that the original file never made it
1013
				unique_id = name_resolver.GetIdByNameAndParentId (old_name, old_dir.UniqueId);
1046
				// into the index ---  thus we treat this as
1014
				if (unique_id == Guid.Empty) {
1047
				// an Add.
1015
					Logger.Log.Warn ("Couldn't find unique id for '{0}' in '{1}' ({2})",
1048
				AddFile (new_dir, new_name);
1016
							 old_name, old_dir.FullName, old_dir.UniqueId);
1017
				return;
1049
				return;
1018
				}
1019
			}
1050
			}
1020
			
1021
			Logger.Log.Debug ("Guid of {0} is {1}", old_path, GuidFu.ToShortString (unique_id));
1022
1051
1023
			string new_path;
1052
			RegisterId (new_name, new_dir, unique_id);
1024
			new_path = Path.Combine (new_dir.FullName, new_name);
1053
1025
			pending_moves_uid_by_path [new_path] = unique_id;
1054
			string old_path;
1055
			old_path = Path.Combine (old_dir.FullName, old_name);
1056
1057
			ForgetId (old_path);
1026
1058
1027
			// FIXME: I think we need to be more conservative when we seen
1059
			// FIXME: I think we need to be more conservative when we seen
1028
			// events in a directory that has not been fully scanned, just to
1060
			// events in a directory that has not been fully scanned, just to
Lines 1111-1123 namespace Beagle.Daemon.FileSystemQuerya Link Here
1111
1143
1112
				// This rename is now in the index, so we no longer need to keep
1144
				// This rename is now in the index, so we no longer need to keep
1113
				// track of the uid in memory.
1145
				// track of the uid in memory.
1114
				pending_moves_uid_by_path.Remove (last_known_path);
1146
				ForgetId (last_known_path);
1115
1147
1116
				return;
1148
				return;
1117
			}
1149
			}
1118
1150
1119
			string path;
1151
			string path;
1120
			path = (string) indexable.LocalState ["Path"];
1152
			path = (string) indexable.LocalState ["Path"];
1153
			ForgetId (path);
1121
1154
1122
			DirectoryModel parent;
1155
			DirectoryModel parent;
1123
			parent = indexable.LocalState ["Parent"] as DirectoryModel;
1156
			parent = indexable.LocalState ["Parent"] as DirectoryModel;
Lines 1159-1164 namespace Beagle.Daemon.FileSystemQuerya Link Here
1159
			if (external_uri == null)
1192
			if (external_uri == null)
1160
				throw new Exception ("No cached external Uri for " + receipt.Uri);
1193
				throw new Exception ("No cached external Uri for " + receipt.Uri);
1161
			receipt.Uri = external_uri;
1194
			receipt.Uri = external_uri;
1195
			ForgetId (external_uri.LocalPath);
1162
		}
1196
		}
1163
1197
1164
		private bool RemapUri (Hit hit)
1198
		private bool RemapUri (Hit hit)

Return to bug 113869