// HUGE REFACTORING NEEDED private void tryMigrate(MetadataServer md) { Dictionary<string, int> sumAccesses = new Dictionary<string, int>(); int averageAll = 0; foreach (string di in md.DataServersInfo.Keys) { int dataAccess = 0; if (md.DataServersInfo[di] != null) { foreach (string file in md.DataServersInfo[di].GetNumberAccesses().Keys) { dataAccess += md.DataServersInfo[di].GetNumberAccesses()[file]; } if (md.DataServersInfo[di].GetNumberAccesses().Count != 0) { sumAccesses.Add(di, dataAccess); } else { sumAccesses.Add(di, 0); } } } int aux = 0; foreach (string di in sumAccesses.Keys) { aux += sumAccesses[di]; } averageAll = (int)(aux / sumAccesses.Count); int min = averageAll - Util.IntervalAccesses(md.Percentage, averageAll); int max = averageAll + Util.IntervalAccesses(md.Percentage, averageAll); List<string> OverloadServers = new List<string>(); List<string> UnderloadServers = new List<string>(); foreach (string s in sumAccesses.Keys) { if (sumAccesses[s] >= max) { OverloadServers.Add(s); } else if (sumAccesses[s] <= min) { UnderloadServers.Add(s); } } if (OverloadServers.Count != 0 && UnderloadServers.Count != 0) { string mostOverloadedServer = ""; string mostUnderloadedServer = ""; long maxFiles = Int64.MinValue; long minFiles = Int64.MaxValue; foreach (string s in OverloadServers) { if (md.DataServersInfo[s].GetTotalAccesses() > maxFiles && md.DataServersInfo[s].GetNumberAccesses().Count > 1) { maxFiles = md.DataServersInfo[s].GetTotalAccesses(); mostOverloadedServer = s; } } string mostAccessedfile = ""; long maxAccesses = Int64.MinValue; if (mostOverloadedServer == null) return; foreach (string f in md.DataServersInfo[mostOverloadedServer].GetNumberAccesses().Keys) { if (md.DataServersInfo[mostOverloadedServer].GetNumberAccesses()[f] > maxAccesses) { maxAccesses = md.DataServersInfo[mostOverloadedServer].GetNumberAccesses()[f]; mostAccessedfile = f; } } while (UnderloadServers.Count != 0) { mostUnderloadedServer = ""; minFiles = Int64.MaxValue; foreach (string s in UnderloadServers) { if (md.DataServersInfo[s].GetTotalAccesses() < minFiles) { minFiles = md.DataServersInfo[s].GetTotalAccesses(); mostUnderloadedServer = s; } } string secondMostAccessedfile; maxAccesses = Int64.MinValue; List<string> previousFiles = new List<string>(); int i = md.DataServersInfo[mostOverloadedServer].GetNumberAccesses().Count; while (i != 0) { secondMostAccessedfile = null; foreach (string f in md.DataServersInfo[mostOverloadedServer].GetNumberAccesses().Keys) { if (f != mostAccessedfile && !previousFiles.Contains(f)) { if (md.DataServersInfo[mostOverloadedServer].GetNumberAccesses()[f] > maxAccesses && (!md.OpenFiles.ContainsKey(f))) { maxAccesses = md.DataServersInfo[mostOverloadedServer].GetNumberAccesses()[f]; secondMostAccessedfile = f; } } } if (secondMostAccessedfile != null) { if (!md.DataServersInfo[mostUnderloadedServer].GetNumberAccesses().ContainsKey(secondMostAccessedfile)) { Console.WriteLine("Migration: File " + secondMostAccessedfile + " from " + mostOverloadedServer + " to " + mostUnderloadedServer); md.getMigratingList().Add(secondMostAccessedfile); md.getMigration().Reset(); Metadata meta = md.Files[secondMostAccessedfile]; string readServer = md.LiveDataServers[mostOverloadedServer]; string writeServer = md.LiveDataServers[mostUnderloadedServer]; IDataServer readDataServer = (IDataServer)Activator.GetObject(typeof(IDataServer), readServer); IDataServer writeDataServer = (IDataServer)Activator.GetObject(typeof(IDataServer), writeServer); File file = readDataServer.Read(secondMostAccessedfile, "default"); string toWrite = Util.ConvertByteArrayToString(file.Content); byte[] content = Util.ConvertStringToByteArray(file.Version.ToString() + (char)0x7f + toWrite); writeDataServer.Write(secondMostAccessedfile, content); readDataServer.RemoveFromDataInfo(secondMostAccessedfile); string command = string.Format("UPDATE {0} {1}", writeServer, secondMostAccessedfile); meta.AddDataServers(writeServer); meta.DataServers.Remove(readServer); md.ServersLoad[mostOverloadedServer]--; List<object> context = new List<object>(); context.Add(md); context.Add(command); md.Log.Append(command); ThreadPool.QueueUserWorkItem(AppendToLog, context); md.getMigration().Set(); md.getMigratingList().Remove(secondMostAccessedfile); return; } else { previousFiles.Add(secondMostAccessedfile); maxAccesses = Int64.MinValue; i--; } } else { UnderloadServers.Remove(mostUnderloadedServer); break; } } } } }
// Project API public override Metadata Open(MetadataServer md, string clientName, string filename) { if (md.getMigratingList().Contains(filename)) { md.getMigration().WaitOne(); } // If already opened by one client if (md.OpenFiles.ContainsKey(filename)) { List<string> clientsList = md.OpenFiles[filename]; if (clientsList.Contains(clientName)) { throw new FileIsOpenedException("File already open."); } md.OpenFiles[filename].Add(clientName); } else { if (!md.Files.ContainsKey(filename)) { throw new FileNotFoundException("File does not exist."); } List<string> clientsList = new List<string>(); clientsList.Add(clientName); md.OpenFiles.Add(filename, clientsList); } List<object> context = new List<object>(); string command = string.Format("OPEN {0} {1}", clientName, filename); context.Add(md); context.Add(command); ThreadPool.QueueUserWorkItem(AppendToLog, context); md.Log.Append(command); return md.Files[filename]; }