Skip to content

Commit b25745b

Browse files
aaronriekenbergGitHub Enterprise
authored andcommitted
Merge pull request #26 from AaronRiekenberg/041522_validate_nma_parameters
Add validateNativeMemoryAllocatorInitialParameters.
2 parents a22210b + 529d584 commit b25745b

File tree

2 files changed

+153
-4
lines changed

2 files changed

+153
-4
lines changed

src/main/kotlin/com/target/nativememoryallocator/allocator/impl/NativeMemoryAllocatorImpl.kt

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,36 @@ import mu.KotlinLogging
99

1010
private val logger = KotlinLogging.logger {}
1111

12+
/**
13+
* Validate initial parameters for [NativeMemoryAllocator].
14+
*
15+
* @param [pageSizeBytes] page size in bytes.
16+
* @param [nativeMemorySizeBytes] native memory size in bytes.
17+
* @throws [IllegalArgumentException] if parameters are invalid.
18+
*/
19+
internal fun validateNativeMemoryAllocatorInitialParameters(
20+
pageSizeBytes: Int,
21+
nativeMemorySizeBytes: Long,
22+
) {
23+
if (pageSizeBytes < 1) {
24+
throw IllegalArgumentException("pageSizeBytes = $pageSizeBytes < 1")
25+
}
26+
27+
if (nativeMemorySizeBytes < 1L) {
28+
throw IllegalArgumentException("nativeMemorySizeBytes = $nativeMemorySizeBytes < 1L")
29+
}
30+
31+
if ((nativeMemorySizeBytes % pageSizeBytes) != 0L) {
32+
throw IllegalArgumentException("nativeMemorySizeBytes = $nativeMemorySizeBytes is not evenly divisible by pageSizeBytes = $pageSizeBytes")
33+
}
34+
35+
val totalNumPages = (nativeMemorySizeBytes / pageSizeBytes)
36+
37+
if (totalNumPages > Int.MAX_VALUE.toLong()) {
38+
throw IllegalArgumentException("totalNumPages = $totalNumPages > Int.MAX_VALUE = ${Int.MAX_VALUE.toLong()}")
39+
}
40+
}
41+
1242
/**
1343
* Implementation of [NativeMemoryAllocator].
1444
*
@@ -31,9 +61,10 @@ internal class NativeMemoryAllocatorImpl(
3161
init {
3262
logger.info { "begin init pageSizeBytes = $pageSizeBytes nativeMemorySizeBytes = $nativeMemorySizeBytes" }
3363

34-
if ((nativeMemorySizeBytes % pageSizeBytes) != 0L) {
35-
throw IllegalStateException("nativeMemorySizeBytes = $nativeMemorySizeBytes is not evenly divisible by pageSizeBytes = $pageSizeBytes")
36-
}
64+
validateNativeMemoryAllocatorInitialParameters(
65+
pageSizeBytes = pageSizeBytes,
66+
nativeMemorySizeBytes = nativeMemorySizeBytes,
67+
)
3768

3869
logger.info { "allocating nativeMemorySizeBytes = $nativeMemorySizeBytes" }
3970
baseNativeMemoryPointer = UnsafeContainer.unsafe.allocateMemory(nativeMemorySizeBytes)

src/test/kotlin/com/target/nativememoryallocator/allocator/impl/NativeMemoryAllocatorImplSpec.kt

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,130 @@ import com.target.nativememoryallocator.buffer.NativeMemoryBuffer
55
import com.target.nativememoryallocator.unsafe.UnsafeContainer
66
import io.mockk.*
77
import org.junit.jupiter.api.Assertions.assertEquals
8+
import org.junit.jupiter.api.Assertions.assertThrows
89
import org.spekframework.spek2.Spek
910
import org.spekframework.spek2.style.gherkin.Feature
1011
import sun.misc.Unsafe
1112

1213
class NativeMemoryAllocatorImplSpec : Spek({
1314
Feature("NativeMemoryAllocatorImpl") {
15+
Scenario("test validateNativeMemoryAllocatorInitialParameters") {
16+
var pageSizeBytes = 0
17+
var nativeMemorySizeBytes = 0L
18+
19+
When("negative pageSizeBytes") {
20+
pageSizeBytes = -1
21+
nativeMemorySizeBytes = 1L * 1024L * 1024L * 1024L
22+
}
23+
Then("validateNativeMemoryAllocatorInitialParameters throws IllegalArgumentException") {
24+
assertThrows(IllegalArgumentException::class.java) {
25+
validateNativeMemoryAllocatorInitialParameters(
26+
pageSizeBytes = pageSizeBytes,
27+
nativeMemorySizeBytes = nativeMemorySizeBytes,
28+
)
29+
}
30+
}
31+
When("zero pageSizeBytes") {
32+
pageSizeBytes = 0
33+
nativeMemorySizeBytes = 1L * 1024L * 1024L * 1024L
34+
}
35+
Then("validateNativeMemoryAllocatorInitialParameters throws IllegalArgumentException") {
36+
assertThrows(IllegalArgumentException::class.java) {
37+
validateNativeMemoryAllocatorInitialParameters(
38+
pageSizeBytes = pageSizeBytes,
39+
nativeMemorySizeBytes = nativeMemorySizeBytes,
40+
)
41+
}
42+
}
43+
When("positive pageSizeBytes") {
44+
pageSizeBytes = 1
45+
nativeMemorySizeBytes = 1L * 1024L * 1024L * 1024L
46+
}
47+
Then("validateNativeMemoryAllocatorInitialParameters does not throw") {
48+
validateNativeMemoryAllocatorInitialParameters(
49+
pageSizeBytes = pageSizeBytes,
50+
nativeMemorySizeBytes = nativeMemorySizeBytes,
51+
)
52+
}
53+
When("max pageSizeBytes") {
54+
pageSizeBytes = Int.MAX_VALUE
55+
nativeMemorySizeBytes = Int.MAX_VALUE.toLong()
56+
}
57+
Then("validateNativeMemoryAllocatorInitialParameters does not throw") {
58+
validateNativeMemoryAllocatorInitialParameters(
59+
pageSizeBytes = pageSizeBytes,
60+
nativeMemorySizeBytes = nativeMemorySizeBytes,
61+
)
62+
}
63+
When("negative nativeMemorySizeBytes") {
64+
pageSizeBytes = 1
65+
nativeMemorySizeBytes = -1L
66+
}
67+
Then("validateNativeMemoryAllocatorInitialParameters throws IllegalArgumentException") {
68+
assertThrows(IllegalArgumentException::class.java) {
69+
validateNativeMemoryAllocatorInitialParameters(
70+
pageSizeBytes = pageSizeBytes,
71+
nativeMemorySizeBytes = nativeMemorySizeBytes,
72+
)
73+
}
74+
}
75+
When("zero nativeMemorySizeBytes") {
76+
pageSizeBytes = 1
77+
nativeMemorySizeBytes = 0L
78+
}
79+
Then("validateNativeMemoryAllocatorInitialParameters throws IllegalArgumentException") {
80+
assertThrows(IllegalArgumentException::class.java) {
81+
validateNativeMemoryAllocatorInitialParameters(
82+
pageSizeBytes = pageSizeBytes,
83+
nativeMemorySizeBytes = nativeMemorySizeBytes,
84+
)
85+
}
86+
}
87+
When("positive nativeMemorySizeBytes") {
88+
pageSizeBytes = 1
89+
nativeMemorySizeBytes = 1L
90+
}
91+
Then("validateNativeMemoryAllocatorInitialParameters does not throw") {
92+
validateNativeMemoryAllocatorInitialParameters(
93+
pageSizeBytes = pageSizeBytes,
94+
nativeMemorySizeBytes = nativeMemorySizeBytes,
95+
)
96+
}
97+
When("positive nativeMemorySizeBytes") {
98+
pageSizeBytes = 4 * 1024
99+
nativeMemorySizeBytes = (1L * 1024L * 1024L * 1024L)
100+
}
101+
Then("validateNativeMemoryAllocatorInitialParameters does not throw") {
102+
validateNativeMemoryAllocatorInitialParameters(
103+
pageSizeBytes = pageSizeBytes,
104+
nativeMemorySizeBytes = nativeMemorySizeBytes,
105+
)
106+
}
107+
When("nativeMemorySizeBytes not evenly divisible by pageSizeBytes") {
108+
pageSizeBytes = 4 * 1024
109+
nativeMemorySizeBytes = (1L * 1024L * 1024L * 1024L) + 1L
110+
}
111+
Then("validateNativeMemoryAllocatorInitialParameters throws IllegalArgumentException") {
112+
assertThrows(IllegalArgumentException::class.java) {
113+
validateNativeMemoryAllocatorInitialParameters(
114+
pageSizeBytes = pageSizeBytes,
115+
nativeMemorySizeBytes = nativeMemorySizeBytes,
116+
)
117+
}
118+
}
119+
When("invalid totalNumPages") {
120+
pageSizeBytes = 1
121+
nativeMemorySizeBytes = (20L * 1024L * 1024L * 1024L)
122+
}
123+
Then("validateNativeMemoryAllocatorInitialParameters throws IllegalArgumentException") {
124+
assertThrows(IllegalArgumentException::class.java) {
125+
validateNativeMemoryAllocatorInitialParameters(
126+
pageSizeBytes = pageSizeBytes,
127+
nativeMemorySizeBytes = nativeMemorySizeBytes,
128+
)
129+
}
130+
}
131+
}
14132
Scenario("test initialization") {
15133
lateinit var mockUnsafe: Unsafe
16134
val pageSizeBytes = 4_096 // 4kb
@@ -152,7 +270,7 @@ class NativeMemoryAllocatorImplSpec : Spek({
152270
nativeMemorySizeBytes = nativeMemorySizeBytes,
153271
zeroNativeMemoryOnStartup = false,
154272
)
155-
} catch (e: IllegalStateException) {
273+
} catch (e: IllegalArgumentException) {
156274
exceptionsCaught += 1
157275
}
158276
}

0 commit comments

Comments
 (0)