1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.kqueue;
17
18 import io.netty.channel.unix.Buffer;
19 import io.netty.util.internal.CleanableDirectBuffer;
20 import io.netty.util.internal.PlatformDependent;
21
22 import java.nio.ByteBuffer;
23
24 import static io.netty.channel.unix.Limits.SIZEOF_JLONG;
25 import static io.netty.util.internal.ObjectUtil.checkPositive;
26
27 final class NativeLongArray {
28 private CleanableDirectBuffer memoryCleanable;
29 private ByteBuffer memory;
30 private long memoryAddress;
31 private int capacity;
32 private int size;
33
34 NativeLongArray(int capacity) {
35 this.capacity = checkPositive(capacity, "capacity");
36 memoryCleanable = Buffer.allocateDirectBufferWithNativeOrder(calculateBufferCapacity(capacity));
37 memory = memoryCleanable.buffer();
38 memoryAddress = Buffer.memoryAddress(memory);
39 }
40
41 private static int idx(int index) {
42 return index * SIZEOF_JLONG;
43 }
44
45 private static int calculateBufferCapacity(int capacity) {
46 return capacity * SIZEOF_JLONG;
47 }
48
49 void add(long value) {
50 reallocIfNeeded();
51 if (PlatformDependent.hasUnsafe()) {
52 PlatformDependent.putLong(memoryOffset(size), value);
53 } else {
54 memory.putLong(idx(size), value);
55 }
56 ++size;
57 }
58
59 void clear() {
60 size = 0;
61 }
62
63 boolean isEmpty() {
64 return size == 0;
65 }
66
67 int size() {
68 return size;
69 }
70
71 void free() {
72 memoryCleanable.clean();
73 memoryAddress = 0;
74 }
75
76 long memoryAddress() {
77 return memoryAddress;
78 }
79
80 long memoryAddressEnd() {
81 return memoryOffset(size);
82 }
83
84 private long memoryOffset(int index) {
85 return memoryAddress + idx(index);
86 }
87
88 private void reallocIfNeeded() {
89 if (size == capacity) {
90
91 int newLength = capacity <= 65536 ? capacity << 1 : capacity + capacity >> 1;
92 int newCapacity = calculateBufferCapacity(newLength);
93 CleanableDirectBuffer buffer = Buffer.allocateDirectBufferWithNativeOrder(newCapacity);
94
95
96 memory.position(0).limit(size);
97 buffer.buffer().put(memory);
98 buffer.buffer().position(0);
99
100 memoryCleanable.clean();
101 memoryCleanable = buffer;
102 memory = buffer.buffer();
103 memoryAddress = Buffer.memoryAddress(memory);
104 capacity = newLength;
105 }
106 }
107
108 @Override
109 public String toString() {
110 return "memoryAddress: " + memoryAddress + " capacity: " + capacity + " size: " + size;
111 }
112 }