////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// public NeBinRelObj Packed() { if (rootNode != null) { Debug.Assert(packed == null); int size = GetSize(); Obj[] keys = new Obj[size]; Obj[] values = new Obj[size]; int count = rootNode.Traverse(keys, values, 0); Debug.Assert(count == size); // packed = new NeBinRelObj(keys, values, true); packed = (NeBinRelObj)Builder.CreateMap(keys, values); //## BAD BAD BAD rootNode = null; } return(packed); }
static int BinRelOrder(NeBinRelObj obj1, NeBinRelObj obj2) { int size1 = obj1.GetSize(); int size2 = obj2.GetSize(); if (size1 != size2) { return(size1 < size2 ? -1 : 1); } int ord = Order(obj1.Col1(), obj2.Col1()); if (ord == 0) { ord = Order(obj1.Col2(), obj2.Col2()); } return(ord); }
////////////////////////////////////////////////////////////////////////////// public override int InternalOrder(Obj other) { Debug.Assert(GetSize() == other.GetSize()); if (other is RecordObj) { return(-other.InternalOrder(this)); } if (other is NeTreeMapObj) { return(-other.InternalOrder(this)); } NeBinRelObj otherRel = (NeBinRelObj)other; int size = GetSize(); Obj[] col = col1; Obj[] otherCol = otherRel.col1; for (int i = 0; i < size; i++) { int ord = col[i].QuickOrder(otherCol[i]); if (ord != 0) { return(ord); } } col = col2; otherCol = otherRel.col2; for (int i = 0; i < size; i++) { int ord = col[i].QuickOrder(otherCol[i]); if (ord != 0) { return(ord); } } return(0); }
///////////////////////////////////////////////////////////////////////////// public static NeBinRelObj Create(Obj[] col1, Obj[] col2, int count) { Debug.Assert(count > 0); IdxSorter sorter1 = null; IdxSorter sorter2 = null; ulong[] keysIdxs = IndexesSortedByHashcode(col1, count); bool isMap = true; int writeIdx = 0; int hashStartIdx = 0; do { uint hashcode = MostSignificant(keysIdxs[hashStartIdx]); int hashEndIdx = hashStartIdx + 1; while (hashEndIdx < count && MostSignificant(keysIdxs[hashEndIdx]) == hashcode) { hashEndIdx++; } if (hashEndIdx - hashStartIdx > 1) { if (sorter1 == null) { sorter1 = new IdxSorter(col1); } sorter1.Sort(keysIdxs, hashStartIdx, hashEndIdx); int keyStartIdx = hashStartIdx; do { Obj key = col1[LeastSignificant(keysIdxs[keyStartIdx])]; int keyEndIdx = keyStartIdx + 1; while (keyEndIdx < hashEndIdx && key.IsEq(col1[LeastSignificant(keysIdxs[keyEndIdx])])) { keyEndIdx++; } int uniqueKeyEndIdx = keyEndIdx; if (keyEndIdx - keyStartIdx > 1) { for (int i = keyStartIdx; i < keyEndIdx; i++) { uint idx = LeastSignificant(keysIdxs[i]); keysIdxs[i] = (((ulong)col2[idx].Hashcode()) << 32) | idx; } Array.Sort(keysIdxs, keyStartIdx, keyEndIdx); if (sorter2 == null) { sorter2 = new IdxSorter(col2); } uniqueKeyEndIdx = SortHashcodeRangeUnique(keysIdxs, keyStartIdx, keyEndIdx, col2, sorter2); if (uniqueKeyEndIdx != keyStartIdx + 1) { isMap = false; } for (int i = keyStartIdx; i < uniqueKeyEndIdx; i++) { keysIdxs[i] = (((ulong)hashcode) << 32) | LeastSignificant(keysIdxs[i]); } } if (keyStartIdx != writeIdx) { for (int i = keyStartIdx; i < uniqueKeyEndIdx; i++) { keysIdxs[writeIdx++] = keysIdxs[i]; } } else { writeIdx += uniqueKeyEndIdx - keyStartIdx; } keyStartIdx = keyEndIdx; } while (keyStartIdx < hashEndIdx); } else { if (hashStartIdx != writeIdx) { keysIdxs[writeIdx] = keysIdxs[hashStartIdx]; } writeIdx++; } hashStartIdx = hashEndIdx; } while (hashStartIdx < count); uint[] hashcodes = new uint[writeIdx]; Obj[] sortedCol1 = new Obj[writeIdx]; Obj[] sortedCol2 = new Obj[writeIdx]; for (int i = 0; i < writeIdx; i++) { ulong keyIdx = keysIdxs[i]; hashcodes[i] = MostSignificant(keyIdx); uint idx = LeastSignificant(keyIdx); sortedCol1[i] = col1[idx]; sortedCol2[i] = col2[idx]; } NeBinRelObj relObj = new NeBinRelObj(sortedCol1, sortedCol2, hashcodes, isMap); // relObj.SelfCheck(col1, col2, count); return(relObj); }