protected void SaveSection(int section) { // Clear the section in chunk if it is cleared in this snapshot if (_palette[section] == null || _palette[section].Count == 0) { _chunk._palette[section]?.Clear(); _chunk._palette[section] = null; _chunk._blockStates[section] = null; return; } // It's possible the section has not been created in chunk var oldCellSize = _chunk._blockStates[section] == null ? -1 : _chunk._blockStates[section].CellSize; // Only update the palette when it is changed if (_paletteChanged[section]) { _chunk._palette[section]?.Clear(); _chunk._palette[section] = _palette[section].Clone(); } var newCellSize = Math.Max(4, NumericUtility.GetRequiredBitLength(_palette[section].Count)); if ((newCellSize == oldCellSize) || (!CompactBlockBitsIfPossible && (newCellSize < oldCellSize))) { // Do not create new DynArray if the cellSize doesn't change to improve performance. var dyn = _chunk._blockStates[section]; for (var i = 0; i < 4096; i++) { dyn[i] = _blocks[section][i]; } } else { // Create new DynArray when cellSize is changed var dyn = DynBitArray.CreateEmpty(newCellSize, 4096); for (var i = 0; i < 4096; i++) { // Because the assignment of dynArray[i] can be time-consuming, // index(0) is skipped because DynBitArray.CreateEmpty is guaranteed to create a zero-filled array if (_blocks[section][i] == 0) { continue; } dyn[i] = _blocks[section][i]; } _chunk._blockStates[section]?.Clear(); _chunk._blockStates[section] = dyn; } }
public void NumericTest() { Assert.AreEqual(NumericUtility.GetRequiredBitLength(2), 1); Assert.AreEqual(NumericUtility.GetRequiredBitLength(4), 2); Assert.AreEqual(NumericUtility.GetRequiredBitLength(8), 3); Assert.AreEqual(NumericUtility.GetRequiredBitLength(7), 3); Assert.AreEqual(NumericUtility.GetRequiredBitLength(9), 4); Assert.AreEqual(NumericUtility.GetLeastMultiplication(4096, 4096), 4096); Assert.AreEqual(NumericUtility.GetLeastMultiplication(8192, 4096), 8192); Assert.AreEqual(NumericUtility.GetLeastMultiplication(8191, 4096), 8192); }