Changes in PithosMonitor and StatusKeeper to detect concurrent changes
[pithos-ms-client] / trunk / Pithos.Core / InMemStatusChecker.cs
1 using System;
2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.ComponentModel.Composition;
5 using System.Diagnostics.Contracts;
6 using System.Linq;
7 using Pithos.Interfaces;
8
9 namespace Pithos.Core
10 {
11     //[Export(typeof(IStatusChecker)),Export(typeof(IStatusKeeper))]
12     public class InMemStatusChecker:IStatusChecker,IStatusKeeper
13     {
14         [Import]
15         public IPithosSettings Settings { get; set; }
16
17         private readonly string[] _states = {"Normal", "Modified", "Conflict","Synch"};
18
19         ConcurrentDictionary<string, FileOverlayStatus> _overlayCache = new ConcurrentDictionary<string, FileOverlayStatus>();
20         ConcurrentDictionary<string, FileStatus> _statusCache = new ConcurrentDictionary<string, FileStatus>();
21         ConcurrentDictionary<string, string> _checksums = new ConcurrentDictionary<string, string>();
22
23         public FileOverlayStatus GetFileOverlayStatus(string path)
24         {
25             if (!_overlayCache.ContainsKey(path))
26                 return FileOverlayStatus.Unversioned;
27
28             var pithosPath = Settings.PithosPath;
29             if (path.StartsWith(pithosPath,true,null))
30             {
31                 var status = _overlayCache[path];
32                 return status;
33             }
34             return FileOverlayStatus.Unversioned;
35         }
36
37         public IEnumerable<string> StoreUnversionedFiles(ParallelQuery<string> paths)
38         {
39
40             var newFiles = (from file in paths
41                             where !_overlayCache.ContainsKey(file)
42                             select new {
43                                            FilePath = file,
44                                            OverlayStatus = FileOverlayStatus.Unversioned,
45                                            FileStatus = FileStatus.Created,
46                                            Checksum = Signature.CalculateHash(file)
47                                        });
48             ConcurrentBag<string> files = new ConcurrentBag<string>();           
49             newFiles.ForAll(state =>
50                                 {
51                                     _overlayCache[state.FilePath] = state.OverlayStatus;
52                                     _statusCache[state.FilePath] = state.FileStatus;
53                                     _checksums[state.FilePath] = state.Checksum;
54                                     files.Add(state.FilePath);
55                                 });
56             return files.GetConsumingEnumerable();
57         }
58
59         public void Stop()
60         {
61             
62         }
63
64
65         private PithosStatus _pithosStatus = PithosStatus.InSynch;
66         public void SetPithosStatus(PithosStatus status)
67         {
68             _pithosStatus = status;
69         }
70
71         public PithosStatus GetPithosStatus()
72         {
73             return _pithosStatus;
74         }
75
76     public void SetStatus(string path, Action<FileState> setter)
77         {
78             throw new NotImplementedException();
79         }
80
81         ConcurrentDictionary<string, NetworkState> _networkState = new ConcurrentDictionary<string, NetworkState>();
82
83     
84         public void SetNetworkState(string path, NetworkState state)
85         {
86             _networkState[path.ToLower()] = state;
87             //Removing may fail so we store the "None" value anyway
88             if (state == NetworkState.None)
89             {
90                 NetworkState oldState;
91                 _networkState.TryRemove(path, out oldState);
92             }
93         }
94
95         public NetworkState GetNetworkState(string path)
96         {
97             NetworkState state;
98             if (_networkState.TryGetValue(path, out state))
99                 return state;
100             return NetworkState.None;
101         }
102
103         public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus)
104         {
105             _overlayCache[path] = overlayStatus;
106         }
107
108         public void RemoveFileOverlayStatus(string path)
109         {
110             FileOverlayStatus value;
111             _overlayCache.TryRemove(path, out value);
112         }
113
114         public void RenameFileOverlayStatus(string oldPath, string newPath)
115         {
116             var status=_overlayCache[oldPath];
117             _overlayCache[newPath] = status;
118             FileOverlayStatus value;
119             _overlayCache.TryRemove(oldPath,out value);
120         }
121
122         public void SetFileStatus(string path, FileStatus status)
123         {
124             _statusCache[path] = status;
125         }
126
127         public void SetFileState(string path, FileStatus fileStatus, FileOverlayStatus overlayStatus)
128         {
129             if (String.IsNullOrWhiteSpace(path))
130                 throw new ArgumentNullException("path","path can't be empty");
131             _statusCache[path] = fileStatus;
132             _overlayCache[path] = overlayStatus;
133         }
134
135         public void StoreInfo(string path, ObjectInfo objectInfo)
136         {
137             if (String.IsNullOrWhiteSpace(path))
138                 throw new ArgumentNullException("path", "path can't be empty");
139             if (objectInfo == null)
140                 throw new ArgumentNullException("objectInfo", "objectInfo can't be empty");
141
142             _statusCache[path] = FileStatus.Unchanged;
143             _overlayCache[path] = FileOverlayStatus.Normal;
144             _checksums[path] = objectInfo.Hash;
145
146
147         }
148
149         public T GetStatus<T>(string path, Func<FileState, T> getter, T defaultValue)
150         {
151             throw new NotImplementedException();
152         }
153
154         public FileStatus GetFileStatus(string path)
155         {
156             if (!_statusCache.ContainsKey(path))
157                 return FileStatus.Missing;
158             return _statusCache[path];
159         }
160
161         public void ClearFileStatus(string path)
162         {
163             FileStatus value;
164             _statusCache.TryRemove(path,out value);
165         }
166
167         public void UpdateFileChecksum(string path, string checksum)
168         {
169             _checksums[path] = checksum;
170         }
171     }
172 }