/// <summary>
        /// 数组排序
        /// </summary>
        /// <typeparam name="valueType">数据类型</typeparam>
        /// <param name="values">待排序数组</param>
        /// <param name="getKey">排序键值获取器</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">排序数据数量</param>
        /// <returns>排序后的数组</returns>
        public static valueType[] GetSort/*Compare[0]*//*Compare[0]*/ <valueType>(valueType[] values, Func <valueType, /*Type[0]*/ ulong /*Type[0]*/> getKey, int startIndex, int count)
        {
            int           length = count * sizeof(/*Type[1]*/ ULongSortIndex /*Type[1]*/);
            UnmanagedPool pool   = AutoCSer.UnmanagedPool.GetDefaultPool(length);

            Pointer.Size data = pool.GetSize(length);
            try
            {
                return(getSort/*Compare[0]*//*Compare[0]*/ (values, getKey, startIndex, count, (/*Type[1]*/ ULongSortIndex /*Type[1]*/ *)data.Data));
            }
            finally { pool.PushOnly(ref data); }
        }
示例#2
0
        /// <summary>
        /// 排序取Top N
        /// </summary>
        /// <typeparam name="valueType">数据类型</typeparam>
        /// <param name="values">待排序数组</param>
        /// <param name="getKey">排序键值获取器</param>
        /// <param name="count">排序数据数量</param>
        /// <returns>排序后的数据</returns>
        private static valueType[] getTop/*Compare[0]*//*Compare[0]*/ <valueType>(valueType[] values, Func <valueType, /*Type[0]*/ ulong /*Type[0]*/> getKey, int count)
        {
            uint          sqrtMod;
            int           length = Math.Min(Math.Max(count << 2, count + (int)AutoCSer.Extension.Number.sqrt((uint)values.Length, out sqrtMod)), values.Length), size = length * sizeof(/*Type[2]*/ ULongSortIndex /*Type[2]*/);
            UnmanagedPool pool = AutoCSer.UnmanagedPool.GetDefaultPool(size);

            Pointer.Size data = pool.GetSize(size);
            try
            {
                return(getTop/*Compare[0]*//*Compare[0]*/ (values, getKey, count, length, (/*Type[2]*/ ULongSortIndex /*Type[2]*/ *)data.Data));
            }
            finally { pool.PushOnly(ref data); }
        }
示例#3
0
        /// <summary>
        /// 数组范围排序
        /// </summary>
        /// <typeparam name="valueType">数据类型</typeparam>
        /// <typeparam name="returnType">返回数据类型</typeparam>
        /// <param name="array">待排序数组</param>
        /// <param name="getKey">排序键值获取器</param>
        /// <param name="skipCount">跳过数据数量</param>
        /// <param name="getCount">排序数据数量</param>
        /// <param name="getValue">获取返回数据</param>
        /// <returns>排序后的数组</returns>
        internal static returnType[] UnsafeGetRangeSort/*Compare[0]*//*Compare[0]*/ <valueType, returnType>(valueType[] array, Func <valueType, /*Type[0]*/ ulong /*Type[0]*/> getKey, int skipCount, int getCount, Func <valueType, returnType> getValue)
        {
            if (getCount == 0)
            {
                return(NullValue <returnType> .Array);
            }
            int           size = array.Length * sizeof(/*Type[2]*/ ULongSortIndex /*Type[2]*/);
            UnmanagedPool pool = AutoCSer.UnmanagedPool.GetDefaultPool(size);

            Pointer.Size data = pool.GetSize(size);
            try
            {
                return(getRangeSort/*Compare[0]*//*Compare[0]*/ (array, getKey, skipCount, getCount, getValue, (/*Type[2]*/ ULongSortIndex /*Type[2]*/ *)data.Data));
            }
            finally { pool.PushOnly(ref data); }
        }
示例#4
0
        /// <summary>
        /// 获取匹配数组
        /// </summary>
        /// <param name="array">数组数据</param>
        /// <param name="isValue">数据匹配器</param>
        /// <returns>匹配数组</returns>
        public static /*Type[0]*/ ulong /*Type[0]*/[] getFindArray(this SubArray </*Type[0]*/ ulong /*Type[0]*/> array, Func </*Type[0]*/ ulong /*Type[0]*/, bool> isValue)
        {
            if (array.Length == 0)
            {
                return(NullValue </*Type[0]*/ ulong /*Type[0]*/> .Array);
            }
            int           length = ((array.Length + 63) >> 6) << 3;
            UnmanagedPool pool   = UnmanagedPool.GetDefaultPool(length);

            Pointer.Size data = pool.GetSize64(length);
            try
            {
                Memory.ClearUnsafe(data.ULong, length >> 3);
                return(FixedArray.GetFindArray(array.Array, array.Start, array.Length, isValue, new MemoryMap(data.Data)));
            }
            finally { pool.PushOnly(ref data); }
        }
示例#5
0
        /// <summary>
        /// 获取匹配数组
        /// </summary>
        /// <typeparam name="valueType">数据类型</typeparam>
        /// <param name="array">数组数据</param>
        /// <param name="isValue">数据匹配器</param>
        /// <returns>匹配数组</returns>
        public unsafe static valueType[] getFindArray <valueType>(this valueType[] array, Func <valueType, bool> isValue)
        {
            int length = array.length();

            if (length == 0)
            {
                return(NullValue <valueType> .Array);
            }
            UnmanagedPool pool = AutoCSer.UnmanagedPool.GetDefaultPool(length = ((length + 63) >> 6) << 3);

            Pointer.Size buffer = pool.GetSize64(length);
            try
            {
                Memory.ClearUnsafe(buffer.ULong, length >> 3);
                return(getFindArray(array, isValue, new MemoryMap(buffer.Data)));
            }
            finally { pool.PushOnly(ref buffer); }
        }
示例#6
0
        /// <summary>
        /// 数组子串排序
        /// </summary>
        /// <typeparam name="valueType">数据类型</typeparam>
        /// <param name="array">待排序数组子串</param>
        /// <param name="getKey">排序键</param>
        /// <param name="index">起始位置</param>
        /// <param name="count">数量</param>
        /// <returns>排序后的数组</returns>
        internal static valueType[] GetSort/*Compare[0]*//*Compare[0]*/ <valueType>(valueType[] array, Func <valueType, /*Type[0]*/ ulong /*Type[0]*/> getKey, int index, int count)
        {
            if (count >= AutoCSer.Algorithm.RadixSort.SortSize64)
            {
                int size = (count << 1) * sizeof(AutoCSer.Algorithm./*Type[1]*/ ULongSortIndex /*Type[1]*/);

                UnmanagedPool pool = AutoCSer.Algorithm.RadixSort.GetUnmanagedPool(size);
                Pointer.Size  data = pool.GetSize(size);
                try
                {
                    AutoCSer.Algorithm./*Type[1]*/ ULongSortIndex /*Type[1]*/ *indexFixed = (AutoCSer.Algorithm./*Type[1]*/ ULongSortIndex /*Type[1]*/ *)data.Data;
                    AutoCSer.Algorithm./*Type[1]*/ ULongSortIndex /*Type[1]*/.Create(indexFixed, array, getKey, index, count);
                    AutoCSer.Algorithm.RadixSort.Sort/*Compare[0]*//*Compare[0]*/ (indexFixed, indexFixed + count, count);
                    return(AutoCSer.Algorithm./*Type[1]*/ ULongSortIndex /*Type[1]*/.Create(indexFixed, array, count));
                }
                finally { pool.PushOnly(ref data); }
            }
            return(AutoCSer.Algorithm.FixedArrayQuickSort.GetSort/*Compare[0]*//*Compare[0]*/ (array, getKey, index, count));
        }
 /// <summary>
 /// 静态哈希字典
 /// </summary>
 /// <param name="values">初始化键值对集合</param>
 public unsafe StaticDictionary(KeyValue <keyType, valueType>[] values)
 {
     if (values.isEmpty())
     {
         indexs = defaultIndexs;
         array  = NullValue <KeyValue <keyType, valueType> > .Array;
     }
     else
     {
         int           length = ((values.Length + 1) >> 1) * (sizeof(int) * 2);
         UnmanagedPool pool   = fastCSharp.UnmanagedPool.GetDefaultPool(length);
         Pointer.Size  data   = pool.GetSize64(length);
         try
         {
             getValues(values, data.Int);
         }
         finally { pool.PushOnly(ref data); }
     }
 }
示例#8
0
        /// <summary>
        /// 添加图片
        /// </summary>
        /// <param name="bitmap">位图</param>
        /// <param name="leftOffset">X方向偏移量</param>
        /// <param name="topOffset">Y方向偏移量</param>
        /// <param name="width">图象宽度</param>
        /// <param name="height">图象高度</param>
        /// <param name="bitmapLeftOffset">位图剪切X方向偏移量</param>
        /// <param name="bitmapTopOffset">位图剪切Y方向偏移量</param>
        /// <param name="isInterlace">图象数据是否连续方式排列,否则使用顺序排列</param>
        /// <param name="maxPixel">最大色彩深度</param>
        /// <returns>图片是否添加成功</returns>
        internal unsafe bool addImage(BitmapData bitmap, int bitmapLeftOffset, int bitmapTopOffset
                                      , int leftOffset, int topOffset, int width, int height, bool isInterlace, byte maxPixel)
        {
            if (fileBuffer == null)
            {
                return(false);

                fixed(Color *colorFixed = colors)
                fixed(int *colorCountFixed = colorCounts)
                {
                    byte * bitmapFixed = (byte *)bitmap.Scan0, currentBitmap = bitmapFixed + bitmap.Stride * (bitmapTopOffset - 1) + (bitmapLeftOffset + width) * 3;
                    Color *currentColor = colorFixed;
                    int    bitMapSpace  = bitmap.Stride - (width << 1) - width;

                    colorIndexs.Empty();
                    for (int colorIndex, row = height; row != 0; --row)
                    {
                        currentBitmap += bitMapSpace;
                        for (int col = width; col != 0; --col)
                        {
                            Color color = new Color {
                                Green = *currentBitmap++, Blue = *currentBitmap++, Red = *currentBitmap++
                            };
                            if (colorIndexs.TryGetValue(color, out colorIndex))
                            {
                                ++colorCountFixed[colorIndex];
                            }
                            else
                            {
                                colorIndexs.Set(color, colorIndex = (int)(currentColor - colorFixed));
                                colorCountFixed[colorIndex]       = 1;
                            }
                            *currentColor++ = color;
                        }
                    }
                    int pixel = ((uint)colorIndexs.Count).bits() - 1;

                    if ((1 << pixel) != colorIndexs.Count)
                    {
                        ++pixel;
                    }
                    if (pixel > maxPixel)
                    {
                        pixel = maxPixel;
                    }
                    else if (pixel < 2)
                    {
                        pixel = 2;
                    }
                    int maxColorCount = 1 << pixel;

                    fixed(byte *bufferFixed = fileBuffer)
                    {
                        byte *currentBuffer = bufferFixed + bufferIndex;

                        *currentBuffer = 0x2c;
                        *(short *)(currentBuffer + 1) = (short)leftOffset;
                        *(short *)(currentBuffer + 3) = (short)topOffset;
                        *(short *)(currentBuffer + 5) = (short)width;
                        *(short *)(currentBuffer + 7) = (short)height;
                        *(currentBuffer + 9)          = (byte)(0x80 + (isInterlace ? 0x40 : 0) + (pixel - 1));
                        if (!checkBuffer(bufferFixed, 10))
                        {
                            return(false);
                        }
                    }

                    if (colorIndexs.Count <= maxColorCount)
                    {
                        fixed(byte *bufferFixed = fileBuffer)
                        {
                            int *currentColorCount = colorCountFixed;

                            foreach (Color colorKey in colorIndexs.Keys)
                            {
                                *currentColorCount++ = colorKey.Value;
                            }
                            Color color             = new Color();
                            int   currentColorIndex = 0;
                            byte *currentBuffer     = bufferFixed + bufferIndex;

                            while (currentColorCount != colorCountFixed)
                            {
                                color.Value = *--currentColorCount;
                                *currentBuffer++ = color.Red;
                                *currentBuffer++ = color.Blue;
                                *currentBuffer++ = color.Green;
                                colorIndexs.Set(color, currentColorIndex++);
                            }
                            *(bufferFixed + bufferIndex + (maxColorCount << 1) + maxColorCount) = (byte)pixel;
                            if (!checkBuffer(bufferFixed, (maxColorCount << 1) + maxColorCount + 1))
                            {
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        int           indexCount = colorIndexs.Count;
                        UnmanagedPool pool       = UnmanagedPool.GetDefaultPool(indexCount * sizeof(IntSortIndex));
                        Pointer.Size  sizeBuffer = pool.GetSize(indexCount * (sizeof(IntSortIndex) + sizeof(int)));
                        int *         buffer     = sizeBuffer.Int;
                        try
                        {
                            IntSortIndex *indexFixed = (IntSortIndex *)(buffer + indexCount), currentSortIndex = indexFixed;
                            foreach (KeyValue <Color, int> colorIndex in colorIndexs.KeyValues)
                            {
                                int color0 = colorIndex.Key.Value;
                                int color3 = ((color0 >> 3) & 0x111111) * 0x1020400;
                                int color2 = ((color0 >> 2) & 0x111111) * 0x1020400;
                                int color1 = ((color0 >> 1) & 0x111111) * 0x1020400;
                                color0 = (color0 & 0x111111) * 0x1020400;
                                (*currentSortIndex++).Set((color3 & 0x70000000) | ((color2 >> 4) & 0x7000000)
                                                          | ((color1 >> 8) & 0x700000) | ((color0 >> 12) & 0x70000) | ((color3 >> 12) & 0x7000)
                                                          | ((color2 >> 16) & 0x700) | ((color1 >> 20) & 0x70) | ((color0 >> 24) & 7), colorIndex.Value);
                            }
                            AutoCSer.Algorithm.FixedArrayQuickSort.sort(indexFixed, indexFixed + indexCount - 1);
                            int *currentSortArray;
                            if (maxColorCount != 2)
                            {
                                currentSortArray = buffer;
                                for (int currentColorCode, lastColorCode = (*--currentSortIndex).Value; currentSortIndex != indexFixed; lastColorCode = currentColorCode)
                                {
                                    currentColorCode = (*--currentSortIndex).Value;
                                    *currentSortArray++ = lastColorCode - currentColorCode;
                                }
                                currentSortArray = buffer + (maxColorCount >> 1) - 2;
                                new AutoCSer.Algorithm.FixedArrayQuickRangeSort.IntRangeSorterDesc {
                                    SkipCount = currentSortArray, GetEndIndex = currentSortArray
                                }.Sort(buffer, buffer + indexCount - 2);
                                int minColorDifference = *currentSortArray, minColorDifferenceCount = 1;
                                while (currentSortArray != buffer)
                                {
                                    if (*--currentSortArray == minColorDifference)
                                    {
                                        ++minColorDifferenceCount;
                                    }
                                }
                                currentSortIndex = indexFixed + indexCount;
                                int maxCountIndex = (*--currentSortIndex).Index, maxCount = *(colorCountFixed + maxCountIndex);
                                for (int currentColorCode, lastColorCode = (*currentSortIndex).Value; currentSortIndex != indexFixed; lastColorCode = currentColorCode)
                                {
                                    currentColorCode = (*--currentSortIndex).Value;
                                    int colorDifference = lastColorCode - currentColorCode;
                                    if (colorDifference >= minColorDifference)
                                    {
                                        if (colorDifference == minColorDifference && --minColorDifferenceCount == 0)
                                        {
                                            ++minColorDifference;
                                        }
                                        *(colorCountFixed + maxCountIndex) = int.MaxValue;
                                        maxCount = *(colorCountFixed + (maxCountIndex = (*currentSortIndex).Index));
                                    }
                                    else
                                    {
                                        int countIndex = (*currentSortIndex).Index, count = *(colorCountFixed + countIndex);
                                        if (count > maxCount)
                                        {
                                            maxCountIndex = countIndex;
                                            maxCount      = count;
                                        }
                                    }
                                }
                                *(colorCountFixed + maxCountIndex) = int.MaxValue;
                            }
                            for (currentSortArray = buffer + indexCount, currentSortIndex = indexFixed; currentSortArray != buffer; *(--currentSortArray) = *(colorCountFixed + (*currentSortIndex++).Index))
                            {
                                ;
                            }
                            currentSortArray = buffer + maxColorCount - 1;
                            new AutoCSer.Algorithm.FixedArrayQuickRangeSort.IntRangeSorterDesc {
                                SkipCount = currentSortArray, GetEndIndex = currentSortArray
                            }.Sort(buffer, buffer + indexCount - 1);
                            int minColorCount = *currentSortArray, minColorCounts = 1;
                            while (currentSortArray != buffer)
                            {
                                if (*--currentSortArray == minColorCount)
                                {
                                    ++minColorCounts;
                                }
                            }
                            fixed(byte *fileBufferFixed = fileBuffer)
                            {
                                byte *        currentBuffer = fileBufferFixed + bufferIndex;
                                IntSortIndex *lastSortIndex = indexFixed, endSortIndex = indexFixed + indexCount;

                                while (*(colorCountFixed + (*lastSortIndex).Index) < minColorCount)
                                {
                                    colorIndexs.Set(*(colorFixed + (*lastSortIndex++).Index), 0);
                                }
                                if (*(colorCountFixed + (*lastSortIndex).Index) == minColorCount && --minColorCounts == 0)
                                {
                                    ++minColorCount;
                                }
                                Color outputColor = *(colorFixed + (*lastSortIndex).Index);

                                *currentBuffer++ = outputColor.Red;
                                *currentBuffer++ = outputColor.Blue;
                                *currentBuffer++ = outputColor.Green;
                                colorIndexs.Set(outputColor, 0);
                                for (--maxColorCount; *(colorCountFixed + (*--endSortIndex).Index) < minColorCount; colorIndexs.Set(*(colorFixed + (*endSortIndex).Index), maxColorCount))
                                {
                                    ;
                                }
                                if (*(colorCountFixed + (*endSortIndex).Index) == minColorCount && --minColorCounts == 0)
                                {
                                    ++minColorCount;
                                }
                                colorIndexs.Set(*(colorFixed + (*endSortIndex).Index), maxColorCount++);
                                int currentColorIndex = 0;

                                for (int *lastColorCount = colorCountFixed + (*endSortIndex).Index; lastSortIndex != endSortIndex;)
                                {
                                    for (*lastColorCount = 0; *(colorCountFixed + (*++lastSortIndex).Index) >= minColorCount; colorIndexs.Set(outputColor, ++currentColorIndex))
                                    {
                                        if (*(colorCountFixed + (*lastSortIndex).Index) == minColorCount && --minColorCounts == 0)
                                        {
                                            ++minColorCount;
                                        }
                                        outputColor = *(colorFixed + (*lastSortIndex).Index);
                                        *currentBuffer++ = outputColor.Red;
                                        *currentBuffer++ = outputColor.Blue;
                                        *currentBuffer++ = outputColor.Green;
                                    }
                                    if (lastSortIndex == endSortIndex)
                                    {
                                        break;
                                    }
                                    *lastColorCount = int.MaxValue;
                                    IntSortIndex *nextSortIndex = lastSortIndex;
                                    while (*(colorCountFixed + (*++nextSortIndex).Index) < minColorCount)
                                    {
                                        ;
                                    }
                                    for (int lastColorCode = (*(lastSortIndex - 1)).Value, nextColorCode = (*nextSortIndex).Value; lastSortIndex != nextSortIndex; ++lastSortIndex)
                                    {
                                        colorIndexs.Set(*(colorFixed + (*lastSortIndex).Index), (*lastSortIndex).Value - lastColorCode <= nextColorCode - (*lastSortIndex).Value ? currentColorIndex : (currentColorIndex + 1));
                                    }
                                    if (lastSortIndex != endSortIndex)
                                    {
                                        if (*(colorCountFixed + (*lastSortIndex).Index) == minColorCount && --minColorCounts == 0)
                                        {
                                            ++minColorCount;
                                        }
                                        outputColor = *(colorFixed + (*lastSortIndex).Index);
                                        *currentBuffer++ = outputColor.Red;
                                        *currentBuffer++ = outputColor.Blue;
                                        *currentBuffer++ = outputColor.Green;
                                        colorIndexs.Set(outputColor, ++currentColorIndex);
                                    }
                                }
                                outputColor = *(colorFixed + (*lastSortIndex).Index);
                                *currentBuffer++ = outputColor.Red;
                                *currentBuffer++ = outputColor.Blue;
                                *currentBuffer++ = outputColor.Green;
                                *currentBuffer   = (byte)pixel;
                                if (!checkBuffer(fileBufferFixed, (maxColorCount << 1) + maxColorCount + 1))
                                {
                                    return(false);
                                }
                            }
                        }
                        finally { pool.Push(ref sizeBuffer); }
                    }
                    byte *colorIndexFixed = (byte *)colorCountFixed;

                    if (isInterlace)
                    {
                        Color *colorEnd   = colorFixed + width * height;
                        int    inputSpace = (width << 3) - width;
                        for (Color *inputColor = colorFixed; inputColor < colorEnd; inputColor += inputSpace)
                        {
                            for (Color *inputEnd = inputColor + width; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++])
                            {
                                ;
                            }
                        }
                        for (Color *inputColor = colorFixed + (width << 2); inputColor < colorEnd; inputColor += inputSpace)
                        {
                            for (Color *inputEnd = inputColor + width; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++])
                            {
                                ;
                            }
                        }
                        inputSpace -= width << 2;
                        for (Color *inputColor = colorFixed + (width << 1); inputColor < colorEnd; inputColor += inputSpace)
                        {
                            for (Color *inputEnd = inputColor + width; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++])
                            {
                                ;
                            }
                        }
                        for (Color *inputColor = colorFixed + width; inputColor < colorEnd; inputColor += width)
                        {
                            for (Color *inputEnd = inputColor + width; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++])
                            {
                                ;
                            }
                        }
                    }
                    else
                    {
                        for (Color *inputColor = colorFixed, inputEnd = colorFixed + width * height; inputColor != inputEnd; *colorIndexFixed++ = (byte)colorIndexs[*inputColor++])
                        {
                            ;
                        }
                    }
                    return(lzwEncode((byte *)colorCountFixed, colorIndexFixed, pixel));
                }
        }