public User FirstUser(Predicate <User> p) { if (p == null) { return(null); // Done to conveniently handle system insertions } // Check if user is scheduled for removal foreach (var entry in toRemove) { if (p(entry)) { return(null); } } // Check loaded users foreach (var entry in loadedUsers) { if (p(entry)) { return(entry); } } // Check modified users foreach (var entry in changeList) { if (p(entry)) { if (!loadedUsers.Contains(entry)) { loadedUsers.Add(entry); } return(entry); } } // Read from database using (var reader = XmlReader.Create(DatabaseName)) { if (!Traverse(reader, MasterEntry)) { return(null); } while ((reader.Name.Equals("User") && reader.NodeType != XmlNodeType.EndElement) || (reader.Read() && reader.NodeType != XmlNodeType.EndElement)) { if (reader.Name.Equals("User")) { User n = FromEncoded(User.Parse(ReadEntry(reader), this)); if (n != null && p(n)) { if (!loadedUsers.Contains(n)) { loadedUsers.Add(n); } return(n); } } } } return(null); }
// Permissive (cache-dependent) flush private void Flush(bool optional) { if (optional && (changeList.Count < 30 && toRemove.Count < 30)) { return; // No need to flush } string temp = GenerateTempFileName("tmp_", ".xml"); using (var writer = XmlWriter.Create(temp)) { using (var reader = XmlReader.Create(DatabaseName)) { int masterDepth = 0; bool trigger = false, wn = false, recent = false, justTriggered = false; while (wn || reader.Read() || (reader.NodeType == XmlNodeType.None && justTriggered)) { justTriggered = false; wn = false; if (trigger) { foreach (var user in changeList) { WriteUser(writer, user); } bool wroteNode = false; while ((wroteNode || reader.Name.Equals("User") || reader.Read()) && reader.NodeType != XmlNodeType.EndElement && reader.NodeType != XmlNodeType.None) { wroteNode = false; if (reader.Name.Equals("User")) { User u = FromEncoded(User.Parse(ReadEntry(reader), this)); if (u != null) { bool shouldWrite = true; foreach (var toChange in changeList) { if (toChange.Name.Equals(u.Name)) { shouldWrite = false; break; } } if (shouldWrite) { foreach (var remove in toRemove) { if (remove.Name.Equals(u.Name)) { shouldWrite = false; break; } } } if (shouldWrite) { WriteUser(writer, u); } } } else { wroteNode = true; writer.WriteNode(reader, true); } } trigger = false; recent = true; writer.WriteEndElement(); toRemove.Clear(); changeList.Clear(); } if (masterDepth != MasterEntry.Length && reader.Name.Equals(MasterEntry[masterDepth])) { trigger = reader.NodeType == XmlNodeType.Element && ++masterDepth == MasterEntry.Length; justTriggered = true; reader.MoveToContent(); writer.WriteStartElement(MasterEntry[masterDepth - 1]); } else if (masterDepth == MasterEntry.Length && recent) { if (masterDepth != 1) { writer.WriteEndElement(); } recent = false; } else { wn = true; writer.WriteNode(reader, true); } } } writer.Flush(); } File.Delete(DatabaseName); File.Move(temp, DatabaseName); }