Revision 89472316

b/trunk/Pithos.Core/Agents/SnapshotDifferencer.cs
43 43
using System.Diagnostics.Contracts;
44 44
using Pithos.Interfaces;
45 45
using Pithos.Network;
46
using System;
47 46
using System.Collections.Generic;
48 47
using System.Linq;
49 48

  
......
81 80
            /// Common objects, lazily evalueated. 
82 81
            /// The common objects are used to calculate both the Changed and Unchanged objects
83 82
            /// </summary>
84
            public readonly Lazy<IEnumerable<ObjectInfo>> Common;
83
            public readonly IEnumerable<ObjectInfo> Common;
85 84

  
86 85
            private readonly static ObjectInfo[] Empty = new ObjectInfo[0];
87 86

  
......
104 103
                CurrentDict = Current.ToDictionary(info => info.UUID);
105 104
                PreviousDict = Previous.ToDictionary(info => info.UUID);
106 105

  
107
                Common=new Lazy<IEnumerable<ObjectInfo>>(() =>
108
                    Current.Join(Previous,
109
                                outKey => outKey.UUID,
110
                                inKey => inKey.UUID,
111
                                (outer, inner) =>outer.SetPrevious(inner)));            
106
                //Attach the previous version to the current listings
107
                foreach (var info in Current)
108
                {
109
                    ObjectInfo prev;
110
                    if (PreviousDict.TryGetValue(info.UUID, out prev))
111
                        info.SetPrevious(prev);
112
                }
113

  
114
                Common=Current.Where(c=>c.Previous !=null);
112 115
            }
113 116
        }
114 117

  
......
116 119
        private State _state;
117 120

  
118 121
        /// <summary>
119
        /// The comparer used to identify common objects.
120
        /// Objects are considered common when they have the same Account, Container and Name
121
        /// </summary>
122
        private readonly ObjectInfoComparer _comparer = new ObjectInfoComparer();
123

  
124
        /// <summary>
125 122
        /// Default constructor. Initializes the Current and Previous listings to empty lists
126 123
        /// </summary>
127 124
        public SnapshotDifferencer()
......
156 153
        
157 154
        /// <summary>
158 155
        /// Deleted objects are those that existed in the Previous listing
159
        /// but are not found in the Current listing, and their UUIDs do not
160
        /// appear in the Current listing (ie they were not renamed/moved)
156
        /// but are not found in the Current listing
161 157
        /// </summary>
162 158
        public IEnumerable<ObjectInfo> Deleted
163 159
        {
164
            get { return _state.Previous.Except(_state.Current,_comparer)
160
            get { return _state.Previous
165 161
                .Where(info=>!_state.CurrentDict.ContainsKey(info.UUID)); }
166 162
        }
167 163

  
168 164
        /// <summary>
169 165
        /// Created objects are those that exist in the Current listing
170
        /// but are not found in the Previous listing, and their UUIDs do not
171
        /// appear in the Previous listing (ie they were not renamed/moved)
166
        /// but are not found in the Previous listing 
172 167
        /// </summary>
173 168
        public IEnumerable<ObjectInfo> Created
174 169
        {
175
            get { return _state.Current.Except(_state.Previous,_comparer)
170
            get { return _state.Current
176 171
                .Where(info=>!_state.PreviousDict.ContainsKey(info.UUID)); }
177 172
        }
178 173
                
179 174
        public IEnumerable<ObjectInfo> Common
180 175
        {
181
            get { return _state.Common.Value; }
176
            get { return _state.Common; }
182 177
        }
183 178

  
184 179
        public IEnumerable<ObjectInfo> Changed
185 180
        {
186 181
            get
187 182
            {
188
                return Common.Where(i => i.PreviousHash != i.Hash && (i.Previous == null ||  i.Uri == i.Previous.Uri));}
183
                return Common.Where(info => 
184
                    //The hash is different
185
                    info.PreviousHash != info.Hash 
186
                    //And the Uri is unchanged or there is no previous version
187
                    && (info.Previous == null ||  info.Uri == info.Previous.Uri));
188
            }
189 189
        }
190

  
191
        /// <summary>
192
        /// Unchanged objects have the same current and previous hash
193
        /// </summary>
190 194
        public IEnumerable<ObjectInfo> Unchanged
191 195
        {
192 196
            get{ return Common.Where(i => i.PreviousHash == i.Hash);}
193 197
        }
194 198

  
199
        /// <summary>
200
        /// Moved objects have a previous version with a different name
201
        /// </summary>
195 202
        public IEnumerable<ObjectInfo>  Moved
196 203
        {
197 204
            get
198
            {
199
                                
200
                return _state.Current.Join(_state.Previous,
201
                                    outer => outer.UUID,
202
                                    inner => inner.UUID,
203
                                    (outer, inner) => (outer.Name == inner.Name ? null : outer.SetPrevious(inner)))
204
                    .Where(t => t != null);                
205
            {                                
206
                return Common.Where(info=>
207
                    //A previous version exists
208
                    info.Previous!= null 
209
                    //and the Uri is different
210
                    && info.Uri!=info.Previous.Uri);                    
205 211
            }
206 212
        }
207 213
    }

Also available in: Unified diff