/// <summary> /// Method to check whether a reordering is required. This fast test /// allows to skip the reordering routine, resulting in a large /// performance increase. /// </summary> internal bool ObjectListRequiresReorder<T>(PwObjectList<T> vItems, PwObjectPool ppOrgStructure, PwObjectPool ppSrcStructure, bool bEntries) where T : class, IStructureItem, IDeepClonable<T> { Debug.Assert(ppOrgStructure.ContainsOnlyType(bEntries ? typeof(PwEntry) : typeof(PwGroup))); Debug.Assert(ppSrcStructure.ContainsOnlyType(bEntries ? typeof(PwEntry) : typeof(PwGroup))); if(vItems.UCount <= 1) return false; if((m_slStatus != null) && !m_slStatus.ContinueWork()) return false; T ptFirst = vItems.GetAt(0); // IStructureItem ptOrg = pgOrgStructure.FindObject(ptFirst.Uuid, true, bEntries); IStructureItem ptOrg = ppOrgStructure.Get(ptFirst.Uuid); if(ptOrg == null) return true; // IStructureItem ptSrc = pgSrcStructure.FindObject(ptFirst.Uuid, true, bEntries); IStructureItem ptSrc = ppSrcStructure.Get(ptFirst.Uuid); if(ptSrc == null) return true; if(ptFirst.ParentGroup == null) { Debug.Assert(false); return true; } PwGroup pgOrgParent = ptOrg.ParentGroup; if(pgOrgParent == null) return true; // Root might be in tree PwGroup pgSrcParent = ptSrc.ParentGroup; if(pgSrcParent == null) return true; // Root might be in tree if(!ptFirst.ParentGroup.Uuid.EqualsValue(pgOrgParent.Uuid)) return true; if(!pgOrgParent.Uuid.EqualsValue(pgSrcParent.Uuid)) return true; List<IStructureItem> lOrg = pgOrgParent.GetObjects(false, bEntries); List<IStructureItem> lSrc = pgSrcParent.GetObjects(false, bEntries); if(vItems.UCount != (uint)lOrg.Count) return true; if(lOrg.Count != lSrc.Count) return true; for(uint u = 0; u < vItems.UCount; ++u) { IStructureItem pt = vItems.GetAt(u); Debug.Assert(pt.ParentGroup == ptFirst.ParentGroup); if(!pt.Uuid.EqualsValue(lOrg[(int)u].Uuid)) return true; if(!pt.Uuid.EqualsValue(lSrc[(int)u].Uuid)) return true; if(pt.LocationChanged != lOrg[(int)u].LocationChanged) return true; if(pt.LocationChanged != lSrc[(int)u].LocationChanged) return true; } return false; }
internal void RelocateGroups(PwObjectPool ppOrgStructure, PwObjectPool ppSrcStructure) { PwObjectList<PwGroup> vGroups = m_pgRootGroup.GetGroups(true); foreach(PwGroup pg in vGroups) { if((m_slStatus != null) && !m_slStatus.ContinueWork()) break; // PwGroup pgOrg = pgOrgStructure.FindGroup(pg.Uuid, true); IStructureItem ptOrg = ppOrgStructure.Get(pg.Uuid); if(ptOrg == null) continue; // PwGroup pgSrc = pgSrcStructure.FindGroup(pg.Uuid, true); IStructureItem ptSrc = ppSrcStructure.Get(pg.Uuid); if(ptSrc == null) continue; PwGroup pgOrgParent = ptOrg.ParentGroup; PwGroup pgSrcParent = ptSrc.ParentGroup; if(pgOrgParent.Uuid.EqualsValue(pgSrcParent.Uuid)) { pg.LocationChanged = ((ptSrc.LocationChanged > ptOrg.LocationChanged) ? ptSrc.LocationChanged : ptOrg.LocationChanged); continue; } if(ptSrc.LocationChanged > ptOrg.LocationChanged) { PwGroup pgLocal = m_pgRootGroup.FindGroup(pgSrcParent.Uuid, true); if(pgLocal == null) { Debug.Assert(false); continue; } if(pgLocal.IsContainedIn(pg)) continue; pg.ParentGroup.Groups.Remove(pg); pgLocal.AddGroup(pg, true); pg.LocationChanged = ptSrc.LocationChanged; } else { Debug.Assert(pg.ParentGroup.Uuid.EqualsValue(pgOrgParent.Uuid)); Debug.Assert(pg.LocationChanged == ptOrg.LocationChanged); } } Debug.Assert(m_pgRootGroup.GetGroups(true).UCount == vGroups.UCount); }
internal void RelocateEntries(PwObjectPool ppOrgStructure, PwObjectPool ppSrcStructure) { PwObjectList<PwEntry> vEntries = m_pgRootGroup.GetEntries(true); foreach(PwEntry pe in vEntries) { if((m_slStatus != null) && !m_slStatus.ContinueWork()) break; // PwEntry peOrg = pgOrgStructure.FindEntry(pe.Uuid, true); IStructureItem ptOrg = ppOrgStructure.Get(pe.Uuid); if(ptOrg == null) continue; // PwEntry peSrc = pgSrcStructure.FindEntry(pe.Uuid, true); IStructureItem ptSrc = ppSrcStructure.Get(pe.Uuid); if(ptSrc == null) continue; PwGroup pgOrg = ptOrg.ParentGroup; PwGroup pgSrc = ptSrc.ParentGroup; if(pgOrg.Uuid.EqualsValue(pgSrc.Uuid)) { pe.LocationChanged = ((ptSrc.LocationChanged > ptOrg.LocationChanged) ? ptSrc.LocationChanged : ptOrg.LocationChanged); continue; } if(ptSrc.LocationChanged > ptOrg.LocationChanged) { PwGroup pgLocal = m_pgRootGroup.FindGroup(pgSrc.Uuid, true); if(pgLocal == null) { Debug.Assert(false); continue; } pe.ParentGroup.Entries.Remove(pe); pgLocal.AddEntry(pe, true); pe.LocationChanged = ptSrc.LocationChanged; } else { Debug.Assert(pe.ParentGroup.Uuid.EqualsValue(pgOrg.Uuid)); Debug.Assert(pe.LocationChanged == ptOrg.LocationChanged); } } Debug.Assert(m_pgRootGroup.GetEntries(true).UCount == vEntries.UCount); }
internal static uint FindLocationChangedPivot<T>(PwObjectList<T> vItems, KeyValuePair<uint, uint> kvpRange, PwObjectPool ppOrgStructure, PwObjectPool ppSrcStructure, Queue<PwUuid> qBefore, Queue<PwUuid> qAfter, bool bEntries) where T : class, IStructureItem, IDeepClonable<T> { uint uPosMax = kvpRange.Key; DateTime dtMax = DateTime.MinValue; List<IStructureItem> vNeighborSrc = null; for(uint u = kvpRange.Key; u <= kvpRange.Value; ++u) { T pt = vItems.GetAt(u); // IStructureItem ptOrg = pgOrgStructure.FindObject(pt.Uuid, true, bEntries); IStructureItem ptOrg = ppOrgStructure.Get(pt.Uuid); if((ptOrg != null) && (ptOrg.LocationChanged > dtMax)) { uPosMax = u; dtMax = ptOrg.LocationChanged; // No 'continue' vNeighborSrc = ptOrg.ParentGroup.GetObjects(false, bEntries); } // IStructureItem ptSrc = pgSrcStructure.FindObject(pt.Uuid, true, bEntries); IStructureItem ptSrc = ppSrcStructure.Get(pt.Uuid); if((ptSrc != null) && (ptSrc.LocationChanged > dtMax)) { uPosMax = u; dtMax = ptSrc.LocationChanged; // No 'continue' vNeighborSrc = ptSrc.ParentGroup.GetObjects(false, bEntries); } } GetNeighborItems(vNeighborSrc, vItems.GetAt(uPosMax).Uuid, qBefore, qAfter); return uPosMax; }