SIL.FieldWorks.FDO.Infrastructure.Impl.SharedXMLBackendProvider.Commit C# (CSharp) Метод

Commit() публичный Метод

public Commit ( HashSet newbies, HashSet dirtballs, HashSet goners ) : bool
newbies HashSet
dirtballs HashSet
goners HashSet
Результат bool
		public override bool Commit(HashSet<ICmObjectOrSurrogate> newbies, HashSet<ICmObjectOrSurrogate> dirtballs, HashSet<ICmObjectId> goners)
		{
			using (m_commitLogMutex.Lock())
			{
				CommitLogMetadata metadata;
				using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream())
				{
					metadata = GetMetadata(stream);
				}

				List<ICmObjectSurrogate> foreignNewbies;
				List<ICmObjectSurrogate> foreignDirtballs;
				List<ICmObjectId> foreignGoners;
				if (GetUnseenForeignChanges(metadata, out foreignNewbies, out foreignDirtballs, out foreignGoners))
				{
					// we have now seen every commit generation
					metadata.Peers[m_peerID].Generation = metadata.CurrentGeneration;

					IUnitOfWorkService uowService = ((IServiceLocatorInternal) m_cache.ServiceLocator).UnitOfWorkService;
					IReconcileChanges reconciler = uowService.CreateReconciler(foreignNewbies, foreignDirtballs, foreignGoners);
					if (reconciler.OkToReconcileChanges())
					{
						reconciler.ReconcileForeignChanges();
						if (metadata.Master == m_peerID)
						{
							var newObjects = new HashSet<ICmObjectOrSurrogate>(foreignNewbies);
							var editedObjects = new HashSet<ICmObjectOrSurrogate>(foreignDirtballs);
							var removedObjects = new HashSet<ICmObjectId>(foreignGoners);

							IEnumerable<CustomFieldInfo> fields;
							if (HaveAnythingToCommit(newObjects, editedObjects, removedObjects, out fields) && (StartupVersionNumber == ModelVersion))
								PerformCommit(newObjects, editedObjects, removedObjects, fields);
						}
					}
					else
					{
						uowService.ConflictingChanges(reconciler);
						SaveMetadata(metadata);
						return true;
					}
				}

				CheckExitedPeerProcesses(metadata);
				if (metadata.Master == Guid.Empty)
				{
					// Check if the former master left the commit log and XML file in a consistent state. If not, we can't continue.
					if (metadata.CurrentGeneration != metadata.FileGeneration)
						throw new InvalidOperationException("The commit log and XML file are in an inconsistent state.");
					base.LockProject();
					metadata.Master = m_peerID;
				}

				IEnumerable<CustomFieldInfo> cfiList;
				if (!HaveAnythingToCommit(newbies, dirtballs, goners, out cfiList) && (StartupVersionNumber == ModelVersion))
				{
					SaveMetadata(metadata);
					return true;
				}

				var commitRec = new CommitLogRecord
					{
						Source = m_peerID,
						WriteGeneration = metadata.CurrentGeneration + 1,
						ObjectsDeleted = goners.Select(g => g.Guid).ToList(),
						ObjectsAdded = newbies.Select(n => n.XMLBytes).ToList(),
						ObjectsUpdated = dirtballs.Select(d => d.XMLBytes).ToList()
					};

				using (var buffer = new MemoryStream())
				{
					Serializer.SerializeWithLengthPrefix(buffer, commitRec, PrefixStyle.Base128, 1);
					if (metadata.LogLength + buffer.Length > m_settings.SharedXMLBackendCommitLogSize)
					{
						// if this peer is the master, then just skip this commit
						// other peers will not be able to continue when it cannot find the missing commit, but
						// the master peer can keep going
						if (metadata.Master != m_peerID)
							throw new InvalidOperationException("The current commit cannot be written to the commit log, because it is full.");
					}
					else
					{
						byte[] bytes = buffer.GetBuffer();
						int commitRecOffset = (metadata.LogOffset + metadata.LogLength) % m_settings.SharedXMLBackendCommitLogSize;
						// check if the record can fit at the end of the commit log. If not, we wrap around to the beginning.
						if (commitRecOffset + buffer.Length > m_settings.SharedXMLBackendCommitLogSize)
						{
							if (metadata.LogLength == 0)
								metadata.LogOffset = 0;
							else
								metadata.Padding = m_settings.SharedXMLBackendCommitLogSize - commitRecOffset;
							metadata.LogLength += metadata.Padding;
							commitRecOffset = 0;
						}
						using (MemoryMappedViewStream stream = m_commitLog.CreateViewStream(commitRecOffset, buffer.Length))
						{
							stream.Write(bytes, 0, (int) buffer.Length);
							metadata.LogLength += (int) buffer.Length;
						}
					}
				}

				if (metadata.Master == m_peerID)
					PerformCommit(newbies, dirtballs, goners, cfiList);

				metadata.CurrentGeneration++;
				// we've seen our own change
				metadata.Peers[m_peerID].Generation = metadata.CurrentGeneration;

				SaveMetadata(metadata);
				return true;
			}
		}