Пример #1
0
		internal void ReorderObjectList<T>(PwObjectList<T> vItems,
			PwObjectPool ppOrgStructure, PwObjectPool ppSrcStructure, bool bEntries)
			where T : class, IStructureItem, IDeepClonable<T>
		{
			if(!ObjectListRequiresReorder<T>(vItems, ppOrgStructure, ppSrcStructure,
				bEntries)) return;

#if DEBUG
			PwObjectList<T> vOrgListItems = vItems.CloneShallow();
#endif

			Queue<KeyValuePair<uint, uint>> qToDo = new Queue<KeyValuePair<uint, uint>>();
			qToDo.Enqueue(new KeyValuePair<uint, uint>(0, vItems.UCount - 1));

			while(qToDo.Count > 0)
			{
				if((m_slStatus != null) && !m_slStatus.ContinueWork()) break;

				KeyValuePair<uint, uint> kvp = qToDo.Dequeue();
				if(kvp.Value <= kvp.Key) { Debug.Assert(false); continue; }

				Queue<PwUuid> qRelBefore = new Queue<PwUuid>();
				Queue<PwUuid> qRelAfter = new Queue<PwUuid>();
				uint uPivot = FindLocationChangedPivot<T>(vItems, kvp, ppOrgStructure,
					ppSrcStructure, qRelBefore, qRelAfter, bEntries);
				T ptPivot = vItems.GetAt(uPivot);

				List<T> vToSort = vItems.GetRange(kvp.Key, kvp.Value);
				Queue<T> qBefore = new Queue<T>();
				Queue<T> qAfter = new Queue<T>();
				bool bBefore = true;

				foreach(T pt in vToSort)
				{
					if(pt == ptPivot) { bBefore = false; continue; }

					bool bAdded = false;
					foreach(PwUuid puBefore in qRelBefore)
					{
						if(puBefore.EqualsValue(pt.Uuid))
						{
							qBefore.Enqueue(pt);
							bAdded = true;
							break;
						}
					}
					if(bAdded) continue;

					foreach(PwUuid puAfter in qRelAfter)
					{
						if(puAfter.EqualsValue(pt.Uuid))
						{
							qAfter.Enqueue(pt);
							bAdded = true;
							break;
						}
					}
					if(bAdded) continue;

					if(bBefore) qBefore.Enqueue(pt);
					else qAfter.Enqueue(pt);
				}
				Debug.Assert(bBefore == false);

				uint uPos = kvp.Key;
				while(qBefore.Count > 0) vItems.SetAt(uPos++, qBefore.Dequeue());
				vItems.SetAt(uPos++, ptPivot);
				while(qAfter.Count > 0) vItems.SetAt(uPos++, qAfter.Dequeue());
				Debug.Assert(uPos == (kvp.Value + 1));

				int iNewPivot = vItems.IndexOf(ptPivot);
				if((iNewPivot < (int)kvp.Key) || (iNewPivot > (int)kvp.Value))
				{
					Debug.Assert(false);
					continue;
				}

				if((iNewPivot - 1) > (int)kvp.Key)
					qToDo.Enqueue(new KeyValuePair<uint, uint>(kvp.Key,
						(uint)(iNewPivot - 1)));

				if((iNewPivot + 1) < (int)kvp.Value)
					qToDo.Enqueue(new KeyValuePair<uint, uint>((uint)(iNewPivot + 1),
						kvp.Value));
			}

#if DEBUG
			foreach(T ptItem in vOrgListItems)
			{
				Debug.Assert(vItems.IndexOf(ptItem) >= 0);
			}
#endif
		}