| // Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'package:cfg/utils/arena.dart'; | |
| import 'package:test/test.dart'; | |
| void main() { | |
| late Uint32Arena arena; | |
| setUp(() { | |
| arena = Uint32Arena(); | |
| }); | |
| test('allocate 0', () { | |
| expect(arena.allocate(0), equals(ArenaPointer.Null)); | |
| expect(arena.allocate(42), isNot(equals(ArenaPointer.Null))); | |
| expect(arena.allocate(0), equals(ArenaPointer.Null)); | |
| }); | |
| test('allocate and access', () { | |
| final ptr1 = arena.allocate(3); | |
| expect(arena[ptr1], equals(0)); | |
| expect(arena[ptr1 + 1], equals(0)); | |
| expect(arena[ptr1 + 2], equals(0)); | |
| arena[ptr1] = 0xabcdef01; | |
| arena[ptr1 + 1] = 0xabcdef02; | |
| arena[ptr1 + 2] = -3; | |
| final ptr2 = arena.allocate(2); | |
| expect(arena[ptr2], equals(0)); | |
| expect(arena[ptr2 + 1], equals(0)); | |
| arena[ptr2] = 0xf00d01; | |
| arena[ptr2 + 1] = 0xf00d02; | |
| expect(arena[ptr1], equals(0xabcdef01)); | |
| expect(arena[ptr1 + 1], equals(0xabcdef02)); | |
| expect(arena[ptr1 + 2], equals(0xfffffffd)); | |
| expect(arena[ptr2], equals(0xf00d01)); | |
| expect(arena[ptr2 + 1], equals(0xf00d02)); | |
| arena[ptr1 + 1] = 123; | |
| expect(arena[ptr1], equals(0xabcdef01)); | |
| expect(arena[ptr1 + 1], equals(123)); | |
| expect(arena[ptr1 + 2], equals(0xfffffffd)); | |
| }); | |
| test('pointer arithmetic', () { | |
| final p1 = arena.allocate(2000); | |
| expect(p1 + 0, equals(p1)); | |
| final p2 = p1 + 1200; | |
| final p3 = p2 + (-511); | |
| final p4 = p3 + (-689); | |
| expect(p4, equals(p1)); | |
| expect(p1 + 689, equals(p3)); | |
| expect((p1 + 17) + 1183, equals(p2)); | |
| expect((p1 + 1491).toInt(), equals((p2 + 291).toInt())); | |
| }); | |
| test('expand', () { | |
| final size1 = Uint32Arena.initialSize - 2; | |
| final p1 = arena.allocate(Uint32Arena.initialSize - 2); | |
| arena[p1] = 0x11111111; | |
| arena[p1 + (size1 - 1)] = 0x22222222; | |
| final p2 = arena.allocate(3); | |
| arena[p2] = 0xf00d0001; | |
| arena[p2 + 1] = 0xf00d0002; | |
| arena[p2 + 2] = 0xf00d0003; | |
| final size3 = Uint32Arena.initialSize << 3; | |
| final p3 = arena.allocate(size3); | |
| for (var i = 0; i < size3; ++i) { | |
| arena[p3 + i] = i << 3; | |
| } | |
| expect(arena[p1], equals(0x11111111)); | |
| expect(arena[p1 + 1], equals(0)); | |
| expect(arena[p1 + (size1 ~/ 2)], equals(0)); | |
| expect(arena[p1 + (size1 - 2)], equals(0)); | |
| expect(arena[p1 + (size1 - 1)], equals(0x22222222)); | |
| expect(arena[p2], equals(0xf00d0001)); | |
| expect(arena[p2 + 1], equals(0xf00d0002)); | |
| expect(arena[p2 + 2], equals(0xf00d0003)); | |
| for (int i = size3 - 1; i >= 0; --i) { | |
| expect(arena[p3 + i], equals(i << 3)); | |
| } | |
| }); | |
| test('double linked list', () { | |
| final n = 10; | |
| final nodes = <ArenaPointer>[]; | |
| ArenaPointer prev = ArenaPointer.Null; | |
| for (var i = 0; i < n; ++i) { | |
| ArenaPointer node = arena.allocate(3); // 3 fields: payload, prev, next. | |
| nodes.add(node); | |
| arena[node] = i; // node.payload = i | |
| arena[node + 1] = prev.toInt(); // node.prev = prev | |
| arena[node + 2] = ArenaPointer.Null.toInt(); // node.next = null | |
| if (prev != ArenaPointer.Null) { | |
| arena[prev + 2] = node.toInt(); // prev.next = node | |
| } | |
| prev = node; | |
| } | |
| // Forward iteration. | |
| var i = 0; | |
| for ( | |
| ArenaPointer node = nodes.first; | |
| node != ArenaPointer.Null; | |
| node = ArenaPointer(arena[node + 2]) | |
| ) { | |
| expect(node, equals(nodes[i])); | |
| expect(arena[node], equals(i)); | |
| ++i; | |
| } | |
| expect(i, equals(n)); | |
| // Backwards iteration. | |
| i = n; | |
| for ( | |
| ArenaPointer node = nodes.last; | |
| node != ArenaPointer.Null; | |
| node = ArenaPointer(arena[node + 1]) | |
| ) { | |
| --i; | |
| expect(node, equals(nodes[i])); | |
| expect(arena[node], equals(i)); | |
| } | |
| expect(i, equals(0)); | |
| }); | |
| } |