public void ChunkedArray_creates_appropriate_number_of_chunks() { int size = 16 * 1024 * 4 + 100; int chunkCount = (int)Math.Ceiling((double)size * sizeof(int) / (16 * 1024)); var array = new ChunkedArray<int>(size); Assert.AreEqual(chunkCount, array.ChunkCount); }
public void ChunkedArray_reports_proper_length() { var length = 16 * 1024 * 4 + 100; var array = new ChunkedArray <int>(length); Assert.AreEqual(length, array.Length); }
public void ChunkedArray_creates_appropriate_number_of_chunks() { int size = 16 * 1024 * 4 + 100; int chunkCount = (int)Math.Ceiling((double)size * sizeof(int) / (16 * 1024)); var array = new ChunkedArray <int>(size); Assert.AreEqual(chunkCount, array.ChunkCount); }
public void Can_get_expected_value_via_indexer() { var n = 16 * 1024 * 2 + 1800; var array = new ChunkedArray<int>(n); for(var i = 0; i < n; i++) { array[i] = 2 * i; } for(var i = 0; i < n; i++) { Assert.AreEqual(2 * i, array[i]); } }
public void Can_enumerate_value_in_proper_order() { var n = 16 * 1024 * 2 + 1800; var array1 = new int[n]; var array2 = new ChunkedArray<int>(n); for(var i = 0; i < n; i++) { array1[i] = i; array2[i] = i; } Assert.AreEqual(array1, array2.ToArray()); }
private static void MyersDiff <T>(T[] before, T[] after, Equality <T> equal, int maxdelta, IList <Tuple <ArrayDiffKind, T> > result) where T : class { // NOTE (steveb): we mark items as 'Added' when they are actually 'Removed' and vice versa; this means the initial 'before' and 'after' arrays must be passed in reversed order as well; // the reason for doing so is that it will show first 'Removed' items, and then the 'Added' ones, which is what the 3-way merge algorithm requires. // initialize temp arrays required for search int max = before.Length + after.Length + 1; var down_array = new ChunkedArray <int>(2 * max + 2); var up_array = new ChunkedArray <int>(2 * max + 2); // run myers diff algorithm MyersDiffRev(after, 0, after.Length - 1, before, 0, before.Length - 1, equal, maxdelta, result, max, down_array, up_array); }
public void Can_enumerate_value_in_proper_order() { var n = 16 * 1024 * 2 + 1800; var array1 = new int[n]; var array2 = new ChunkedArray <int>(n); for (var i = 0; i < n; i++) { array1[i] = i; array2[i] = i; } Assert.AreEqual(array1, array2.ToArray()); }
public void Can_get_expected_value_via_indexer() { var n = 16 * 1024 * 2 + 1800; var array = new ChunkedArray <int>(n); for (var i = 0; i < n; i++) { array[i] = 2 * i; } for (var i = 0; i < n; i++) { Assert.AreEqual(2 * i, array[i]); } }
private static void MyersDiffRev <T>(T[] before, int i_start, int i_end, T[] after, int j_start, int j_end, Equality <T> equal, int maxdelta, IList <Tuple <ArrayDiffKind, T> > result, int max, ChunkedArray <int> down_array, ChunkedArray <int> up_array) where T : class { // NOTE (steveb): we mark items as 'Added' when they are actually 'Removed' and vice versa; this means the initial 'before' and 'after' arrays must be passed in reversed order as well; // the reason for doing so is that it will show first 'Removed' items, and then the 'Added' ones, which is what the 3-way merge algorithm requires. // skip matching items at the beginning while ((i_start <= i_end) && (j_start <= j_end) && equal(before[i_start], after[j_start])) { // add skipped item result.Add(new Tuple <ArrayDiffKind, T>(ArrayDiffKind.Same, before[i_start])); // move diagonally ++i_start; ++j_start; } // skip matching items at the end int tailCopyCount = 0; while ((i_start <= i_end) && (j_start <= j_end) && equal(before[i_end], after[j_end])) { // count skipped items ++tailCopyCount; // move diagonally --i_end; --j_end; } // check if we found a terminal case or if new need to recurse if (j_start > j_end) { // add remaining items as 'removed' while (i_start <= i_end) { result.Add(new Tuple <ArrayDiffKind, T>(ArrayDiffKind.Added, before[i_start++])); } } else if (i_start > i_end) { // add remaining items as 'added' while (j_start <= j_end) { result.Add(new Tuple <ArrayDiffKind, T>(ArrayDiffKind.Removed, after[j_start++])); } } else { // find the optimal path int i_split; int j_split; ComputeMyersSplit(before, i_start, i_end, out i_split, after, j_start, j_end, out j_split, equal, maxdelta, max, down_array, up_array); // solve sub-problem MyersDiffRev(before, i_start, i_split - 1, after, j_start, j_split - 1, equal, maxdelta, result, max, down_array, up_array); MyersDiffRev(before, i_split, i_end, after, j_split, j_end, equal, maxdelta, result, max, down_array, up_array); } // add tail items for (int k = 1; k <= tailCopyCount; ++k) { result.Add(new Tuple <ArrayDiffKind, T>(ArrayDiffKind.Same, before[i_end + k])); } }
private static void ComputeMyersSplit <T>(T[] before, int i_start, int i_end, out int i_split, T[] after, int j_start, int j_end, out int j_split, Equality <T> equal, int maxdelta, int max, ChunkedArray <int> down_array, ChunkedArray <int> up_array) { // check if problem space is odd or even sized bool odd = (((i_end - i_start + 1) - (j_end - j_start + 1)) & 1) != 0; // the k-line to start the forward search int down_k = i_start - j_start; // the k-line to start the reverse search int up_k = i_end - j_end; // The vectors in the publication accepts negative indexes. the vectors implemented here are 0-based // and are access using a specific offset: UpOffset UpVector and DownOffset for DownVektor int down_offset = max - down_k; int up_offset = max - up_k; // initialize arrays down_array[down_offset + down_k + 1] = i_start; up_array[up_offset + up_k - 1] = i_end + 1; // find furthest reaching D-path int d_max = (((i_end - i_start + 1) + (j_end - j_start + 1) + 1) / 2); if (d_max >= maxdelta) { throw new ExceededDeltaException(); } for (int d = 0; d <= d_max; ++d) { // search forward for (int k = down_k - d; k <= down_k + d; k += 2) { // find the only or better starting point int x; int y; if (k == down_k - d) { x = down_array[down_offset + k + 1]; // down } else { x = down_array[down_offset + k - 1] + 1; // a step to the right if ((k < down_k + d) && (down_array[down_offset + k + 1] >= x)) { x = down_array[down_offset + k + 1]; // down } } y = x - k; // find the end of the furthest reaching forward D-path in diagonal k while ((x <= i_end) && (y <= j_end) && equal(before[x], after[y])) { ++x; ++y; } down_array[down_offset + k] = x; // overlap ? if (odd && (up_k - d < k) && (k < up_k + d)) { if (up_array[up_offset + k] <= down_array[down_offset + k]) { i_split = down_array[down_offset + k]; j_split = down_array[down_offset + k] - k; return; } } } // search backwards for (int k = up_k - d; k <= up_k + d; k += 2) { // find the only or better starting point int x; int y; if (k == up_k + d) { x = up_array[up_offset + k - 1]; // up } else { x = up_array[up_offset + k + 1] - 1; // left if ((k > up_k - d) && (up_array[up_offset + k - 1] < x)) { x = up_array[up_offset + k - 1]; // up } } y = x - k; while ((x > i_start) && (y > j_start) && equal(before[x - 1], after[y - 1])) { --x; --y; // diagonal } up_array[up_offset + k] = x; // overlap ? if (!odd && (down_k - d <= k) && (k <= down_k + d)) { if (up_array[up_offset + k] <= down_array[down_offset + k]) { i_split = down_array[down_offset + k]; j_split = down_array[down_offset + k] - k; return; } } } } throw new InvalidOperationException("this should never happen"); }
public void ChunkedArray_reports_proper_length() { var length = 16 * 1024 * 4 + 100; var array = new ChunkedArray<int>(length); Assert.AreEqual(length, array.Length); }
void Update() { var ms = MusicManager.MusicState; while (_thoughts.Count < ThoughtCount) { var newThought = Instantiate(ThoughtPrefab.gameObject); newThought.transform.SetParent(transform); var newT = new Thought() { Transform = newThought.transform, }; newT.Destination = newThought.transform.localPosition; _thoughts.Add(newT); } for (var i = 0; i < _thoughts.Count; ++i) { var t = _thoughts[i]; if (Vector3.Distance(t.Destination, t.Transform.localPosition) < .1f) { Random.InitState(Time.frameCount + i); t.Destination = new Vector3(Random.Range(-CellRadius, CellRadius) * GridSize, Random.Range(-CellRadius, CellRadius) * GridSize, Random.Range(-CellRadius, CellRadius) * GridSize); } t.Transform.localPosition = Vector3.MoveTowards(t.Transform.localPosition, t.Destination, ThoughtSpeed * ms.Peak); } var cellDiameter = CellRadius * 2; var totalRadius = (CellRadius * GridSize) / 2f; var arraySize = (cellDiameter + 1) * (cellDiameter + 1) * (cellDiameter + 1); if (_matrices == null || _matrices.Count != arraySize) { _matrices = new ChunkedArray <Matrix4x4>(arraySize, 1023); } bool lastPhase = false; int counter = 0; for (var x = -CellRadius; x < CellRadius; ++x) { lastPhase = !lastPhase; for (var y = -CellRadius; y < CellRadius; ++y) { lastPhase = !lastPhase; for (var z = -CellRadius; z < CellRadius; ++z) { var phase = GetPhase(lastPhase ? 1 : 0) * GridSize; lastPhase = !lastPhase; var pos = new Vector3(x, y, z) * GridSize + phase; int magicInt = ((x + y) * z); Random.InitState(magicInt); var wl = Mathf.Lerp(ms.Wavelength[Random.Range(0, ms.Wavelength.Length - 1)] % 1, 1, ScaleMultiplier); var s = Scale.x + (Scale.y - Scale.x) * wl; var mat = Matrix4x4.TRS(pos, Quaternion.identity, Vector3.one * s * GridSize); mat = transform.localToWorldMatrix * mat; _matrices[counter] = mat; counter++; } } } foreach (Matrix4x4[] matrixArray in _matrices) { Graphics.DrawMeshInstanced(GridMesh, 0, GridMaterial, matrixArray, matrixArray.Length, null, ShadowCastingMode.Off, false, 0, null); } }