Beispiel #1
0
        //////////////////////////////////////////////////////////////////////////////

        private static int SortHashcodeRangeUnique(ulong[] keysIdxs, int start, int end, Obj[] objs, IdxSorter sorter)
        {
            int writeIdx     = start;
            int hashStartIdx = start;

            do
            {
                uint hashcode   = MostSignificant(keysIdxs[hashStartIdx]);
                int  hashEndIdx = hashStartIdx + 1;
                while (hashEndIdx < end && MostSignificant(keysIdxs[hashStartIdx]) == hashcode)
                {
                    hashEndIdx++;
                }

                if (hashEndIdx - hashStartIdx > 1)
                {
                    sorter.Sort(keysIdxs, hashStartIdx, hashEndIdx);

                    int idx = hashStartIdx;
                    do
                    {
                        if (idx != writeIdx)
                        {
                            keysIdxs[writeIdx] = keysIdxs[idx];
                        }
                        writeIdx++;

                        Obj obj = objs[LeastSignificant(keysIdxs[idx++])];
                        while (idx < hashEndIdx && obj.IsEq(objs[LeastSignificant(keysIdxs[idx])]))
                        {
                            idx++;
                        }
                    } while (idx < hashEndIdx);
                }
                else
                {
                    if (hashStartIdx != writeIdx)
                    {
                        keysIdxs[writeIdx] = keysIdxs[hashStartIdx];
                    }
                    writeIdx++;
                }

                hashStartIdx = hashEndIdx;
            } while (hashStartIdx < end);

            return(writeIdx);
        }
Beispiel #2
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);
        }