public static size_t BuildDTable()

in csharp/src/FseDecompress.cs [111:181]


		public static size_t BuildDTable(FSE_DTable* dt, short[] normalizedCounter, uint maxSymbolValue, uint tableLog)
		{
			void* tdPtr = dt + 1;   /* because *dt is unsigned, 32-bits aligned on 32-bits */
			FSE_DECODE_TYPE* tableDecode = (FSE_DECODE_TYPE*)(tdPtr);
			U16[] symbolNext = new U16[Fse.FSE_MAX_SYMBOL_VALUE + 1];

			U32 maxSV1 = maxSymbolValue + 1;
			U32 tableSize = (U32)1 << (int)tableLog;
			U32 highThreshold = tableSize - 1;

			/* Sanity Checks */
			if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(Error.maxSymbolValue_tooLarge);
			if (tableLog > FSE_MAX_TABLELOG) return ERROR(Error.tableLog_tooLarge);

			/* Init, lay down lowprob symbols */
			{
				FSE_DTableHeader DTableH;
				DTableH.tableLog = (U16)tableLog;
				DTableH.fastMode = 1;
				{
					S16 largeLimit = (S16)(1 << (int)(tableLog - 1));
					U32 s;
					for (s = 0; s < maxSV1; s++)
					{
						if (normalizedCounter[s] == -1)
						{
							tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
							symbolNext[s] = 1;
						}
						else
						{
							if (normalizedCounter[s] >= largeLimit) DTableH.fastMode = 0;
							symbolNext[s] = (U16)normalizedCounter[s];
						}
					}
				}
				*(FSE_DTableHeader*)dt = DTableH; // memcpy(dt, &DTableH, sizeof(DTableH));
			}

			/* Spread symbols */
			{
				U32 tableMask = tableSize - 1;
				U32 step = FSE_TABLESTEP(tableSize);
				U32 s, position = 0;
				for (s = 0; s < maxSV1; s++)
				{
					int i;
					for (i = 0; i < normalizedCounter[s]; i++)
					{
						tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
						position = (position + step) & tableMask;
						while (position > highThreshold) position = (position + step) & tableMask;   /* lowprob area */
					}
				}
				if (position != 0) return ERROR(Error.GENERIC);   /* position must reach all cells once, otherwise normalizedCounter is incorrect */
			}

			/* Build Decoding table */
			{
				U32 u;
				for (u = 0; u < tableSize; u++)
				{
					FSE_FUNCTION_TYPE symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol);
					U32 nextState = symbolNext[symbol]++;
					tableDecode[u].nbBits = (BYTE)(tableLog - BIT_highbit32(nextState));
					tableDecode[u].newState = (U16)((nextState << tableDecode[u].nbBits) - tableSize);
				}
			}

			return 0;
		}