/// <summary> /// Calculates the sequence in which files should be deleted based on their releations. /// </summary> /// <returns>The deletable volumes.</returns> /// <param name="deleteableVolumes">Block volumes slated for deletion.</param> public IEnumerable <IRemoteVolume> GetDeletableVolumes(IEnumerable <IRemoteVolume> deleteableVolumes, System.Data.IDbTransaction transaction) { using (var cmd = m_connection.CreateCommand()) { // Although the generated index volumes are always in pairs, // this code handles many-to-many relations between // index files and block volumes, should this be added later var lookupBlock = new Dictionary <string, List <IRemoteVolume> >(); var lookupIndexfiles = new Dictionary <string, List <string> >(); cmd.Transaction = transaction; using (var rd = cmd.ExecuteReader(@"SELECT ""C"".""Name"", ""B"".""Name"", ""B"".""Hash"", ""B"".""Size"" FROM ""IndexBlockLink"" A, ""RemoteVolume"" B, ""RemoteVolume"" C WHERE ""A"".""IndexVolumeID"" = ""B"".""ID"" AND ""A"".""BlockVolumeID"" = ""C"".""ID"" AND ""B"".""Hash"" IS NOT NULL AND ""B"".""Size"" IS NOT NULL ")) while (rd.Read()) { var name = rd.GetValue(0).ToString(); List <IRemoteVolume> indexfileList; if (!lookupBlock.TryGetValue(name, out indexfileList)) { indexfileList = new List <IRemoteVolume>(); lookupBlock.Add(name, indexfileList); } var v = new RemoteVolume(rd.GetString(1), rd.GetString(2), rd.GetInt64(3)); indexfileList.Add(v); List <string> blockList; if (!lookupIndexfiles.TryGetValue(v.Name, out blockList)) { blockList = new List <string>(); lookupIndexfiles.Add(v.Name, blockList); } blockList.Add(name); } foreach (var r in deleteableVolumes.Distinct()) { // Return the input yield return(r); List <IRemoteVolume> indexfileList; if (lookupBlock.TryGetValue(r.Name, out indexfileList)) { foreach (var sh in indexfileList) { List <string> backref; if (lookupIndexfiles.TryGetValue(sh.Name, out backref)) { //If this is the last reference, // remove the index file as well if (backref.Remove(r.Name) && backref.Count == 0) { yield return(sh); } } } } } } }
/// <summary> /// Calculates the sequence in which files should be deleted based on their releations. /// </summary> /// <returns>The deletable volumes.</returns> /// <param name="deleteableVolumes">Block volumes slated for deletion.</param> public IEnumerable<IRemoteVolume> GetDeletableVolumes(IEnumerable<IRemoteVolume> deleteableVolumes, System.Data.IDbTransaction transaction) { using(var cmd = m_connection.CreateCommand()) { // Although the generated index volumes are always in pairs, // this code handles many-to-many relations between // index files and block volumes, should this be added later var lookupBlock = new Dictionary<string, List<IRemoteVolume>>(); var lookupIndexfiles = new Dictionary<string, List<string>>(); cmd.Transaction = transaction; using(var rd = cmd.ExecuteReader(@"SELECT ""C"".""Name"", ""B"".""Name"", ""B"".""Hash"", ""B"".""Size"" FROM ""IndexBlockLink"" A, ""RemoteVolume"" B, ""RemoteVolume"" C WHERE ""A"".""IndexVolumeID"" = ""B"".""ID"" AND ""A"".""BlockVolumeID"" = ""C"".""ID"" AND ""B"".""Hash"" IS NOT NULL AND ""B"".""Size"" IS NOT NULL ")) while(rd.Read()) { var name = rd.GetValue(0).ToString(); List<IRemoteVolume> indexfileList; if (!lookupBlock.TryGetValue(name, out indexfileList)) { indexfileList = new List<IRemoteVolume>(); lookupBlock.Add(name, indexfileList); } var v = new RemoteVolume(rd.GetValue(1).ToString(), rd.GetValue(2).ToString(), Convert.ToInt64(rd.GetValue(3))); indexfileList.Add(v); List<string> blockList; if (!lookupIndexfiles.TryGetValue(v.Name, out blockList)) { blockList = new List<string>(); lookupIndexfiles.Add(v.Name, blockList); } blockList.Add(name); } foreach(var r in deleteableVolumes.Distinct()) { // Return the input yield return r; List<IRemoteVolume> indexfileList; if (lookupBlock.TryGetValue(r.Name, out indexfileList)) foreach(var sh in indexfileList) { List<string> backref; if (lookupIndexfiles.TryGetValue(sh.Name, out backref)) { //If this is the last reference, // remove the index file as well if (backref.Remove(r.Name) && backref.Count == 0) yield return sh; } } } } }