|
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) |