// Replica metadata server append to log public override void AppendToLog(MetadataServer md, string command) { string[] args = command.Split(' '); string code = args[0]; switch (code) { case "CREATE": { string clientName = args[1]; string filename = args[2]; int serversNumber = int.Parse(args[3]); int readQuorum = int.Parse(args[4]); int writeQuorum = int.Parse(args[5]); if (!md.Files.ContainsKey(filename)) { if (md.LiveDataServers.Count < serversNumber) { if (!md.PendingFiles.ContainsKey(filename)) { md.PendingFiles.Add(filename, serversNumber - md.LiveDataServers.Count); } } List<string> servers = new List<string>(); string[] chosen = Util.SliceArray(args, 6, args.Length); // Before sending the requests, a time stamp is added to the filename foreach (string v in chosen) { servers.Add(md.LiveDataServers[v]); md.ServersLoad[v]++; } md.ServersLoad = Util.SortServerLoad(md.ServersLoad); Metadata meta = new Metadata(filename, serversNumber, readQuorum, writeQuorum, servers); List<string> clientsList = new List<string>(); clientsList.Add(clientName); md.Files.Add(filename, meta); md.OpenFiles.Add(filename, clientsList); } } break; case "OPEN": { string clientName = args[1]; string filename = args[2]; if (md.OpenFiles.ContainsKey(filename)) { List<string> clientsList = md.OpenFiles[filename]; if (!clientsList.Contains(clientName)) { md.OpenFiles[filename].Add(clientName); } } else { if (md.Files.ContainsKey(filename)) { List<string> clientsList = new List<string>(); clientsList.Add(clientName); md.OpenFiles.Add(filename, clientsList); } } } break; case "CLOSE": { string clientName = args[1]; string filename = args[2]; if (md.Files.ContainsKey(filename)) { if (md.OpenFiles.ContainsKey(filename)) { List<string> clientsList = md.OpenFiles[filename]; if (clientsList.Contains(clientName)) { clientsList.Remove(clientName); if (clientsList.Count == 0) { md.OpenFiles.Remove(filename); } } } } } break; case "DELETE": { string clientName = args[1]; string filename = args[2]; string[] servers = Util.SliceArray(args, 3, args.Length); if (md.Files.ContainsKey(filename)) { md.Files.Remove(filename); md.OpenFiles.Remove(filename); foreach (string server in servers) { md.ServersLoad[server]--; } md.ServersLoad = Util.SortServerLoad(md.ServersLoad); } } break; case "REGISTER": { string server = args[1]; string name = args[2]; string address = args[3]; switch (server) { case "data": if (!md.DataServersInfo.ContainsKey(name)) { md.LiveDataServers.Add(name, address); md.DataServersInfo.Add(name, null); md.ServersLoad.Add(name, 0); } break; case "metadata": if (!md.Replicas.ContainsKey(name) && name != md.Name) { md.Replicas.Add(name, address); } break; case "client": if (!md.Clients.ContainsKey(name)) { md.Clients.Add(name, address); } break; } } break; case "UPDATE": { string name = args[1]; string address = args[2]; string[] files = Util.SliceArray(args, 3, args.Length); SerializableDictionary<string, int> updated = new SerializableDictionary<string, int>(); bool contains = false; foreach (string f in files) { Metadata meta = md.Files[f]; meta.AddDataServers(address); md.ServersLoad[name]++; md.ServersLoad = Util.SortServerLoad(md.ServersLoad); if (md.PendingFiles.ContainsKey(f)) { int n = md.PendingFiles[f] - 1; if (n > 0) { updated.Add(f, n); } contains = true; } } if (contains) { md.PendingFiles = new SerializableDictionary<string, int>(updated); } } break; case "SET-PRIMARY": { string primary = args[1]; md.Primary = primary; if (md.Primary == md.Name) { md.EnablePrimaryTimers(); } else { md.EnableReplicaTimers(); } } break; case "TOKEN": { long s = long.Parse(args[1]); md.Sequencer = s; } break; } md.Log.Append(command); }
// Method used to add a new/open file to a free file register // Limit - 10 private void AddToFileRegister(Metadata meta) { fileRegister[nextRegister] = meta; nextRegister = (nextRegister + 1) % registersLimit; }
public override Metadata Create(MetadataServer md, string clientName, string filename, int serversNumber, int readQuorum, int writeQuorum) { if (md.Files.ContainsKey(filename)) { throw new FileAlreadyExists("File already exists."); } if (md.LiveDataServers.Count < serversNumber) { if (!md.PendingFiles.ContainsKey(filename)) { md.PendingFiles.Add(filename, serversNumber - md.LiveDataServers.Count); } } List<string> servers = new List<string>(); List<string> chosen = ChooseBestServers(serversNumber, md); // Before sending the requests, a time stamp is added to the filename string f = md.GetToken().ToString() + (char)0x7f + filename; foreach (string v in chosen) { List<string> arguments = new List<string>(); arguments.Add(md.LiveDataServers[v]); arguments.Add(f); servers.Add(md.LiveDataServers[v]); ThreadPool.QueueUserWorkItem(CreateCallback, arguments); md.ServersLoad[v]++; } LoadBalanceServers(md); Metadata meta = new Metadata(filename, serversNumber, readQuorum, writeQuorum, servers); List<string> clientsList = new List<string>(); clientsList.Add(clientName); md.Files.Add(filename, meta); md.OpenFiles.Add(filename, clientsList); List<object> context = new List<object>(); context.Add(md); string command = string.Format("CREATE {0} {1} {2} {3} {4}", clientName, filename, serversNumber, readQuorum, writeQuorum); foreach (string c in chosen) { command += string.Format(" {0}", c); } context.Add(command); ThreadPool.QueueUserWorkItem(AppendToLog, context); md.Log.Append(command); return meta; }
public void UpdateFileMetadata(string filename, Metadata metadata) { if (openFiles.ContainsKey(filename)) { openFiles[filename] = metadata; for (int i = 0; i < registersLimit; i++) { if (fileRegister[i] != null && fileRegister[i].Filename == filename) { fileRegister[i] = metadata; break; } } } }