Skip to content

Commit 6c2d4d4

Browse files
authored
Small Benchmarks improvements (#25)
feat: enhance n-ary tree operations and standardize Gatling action names Add tree traversal methods to NAryTreeBuilder: - childrenOf(): compute all child node ordinals for a given parent - siblingsOf(): compute all sibling node ordinals for a given node Standardize Gatling HTTP action names for consistent reporting: - "Create XXX" for entity creation - "Fetch single XXX" for individual entity retrieval - "Fetch child XXX" for bulk child entity retrieval - "Update XXX" for entity updates - "Check XXX exists" for existence validation This improves benchmark report readability and provides more tree navigation utilities for hierarchical namespace operations.
1 parent 564556d commit 6c2d4d4

File tree

5 files changed

+62
-30
lines changed

5 files changed

+62
-30
lines changed

benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/NAryTreeBuilder.scala

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,22 @@ case class NAryTreeBuilder(nsWidth: Int, nsDepth: Int) {
4747
pathToRoot(parent, ordinal :: acc)
4848
}
4949

50+
/**
51+
* Computes the ordinals of all child nodes for a given node.
52+
*
53+
* @param ordinal the ordinal of the parent node
54+
* @return a list of ordinals representing the child nodes
55+
*/
56+
def childrenOf(ordinal: Int): List[Int] =
57+
if (depthOf(ordinal) >= nsDepth - 1) {
58+
// Node is a leaf, has no children
59+
List.empty
60+
} else {
61+
// For a node with ordinal p, its children have ordinals: p*nsWidth + 1, p*nsWidth + 2, ..., p*nsWidth + nsWidth
62+
val firstChild = ordinal * nsWidth + 1
63+
(firstChild until firstChild + nsWidth).toList
64+
}
65+
5066
/**
5167
* Calculates the depth of a node in the n-ary tree based on its ordinal.
5268
*
@@ -100,4 +116,21 @@ case class NAryTreeBuilder(nsWidth: Int, nsDepth: Int) {
100116
val lastLevel = nsDepth - 1
101117
math.pow(nsWidth, lastLevel).toInt
102118
}
119+
120+
/**
121+
* Computes the ordinals of all sibling nodes for a given node.
122+
*
123+
* @param ordinal the ordinal of the node
124+
* @return a list of ordinals representing the sibling nodes (excluding the node itself)
125+
*/
126+
def siblingsOf(ordinal: Int): List[Int] =
127+
if (ordinal == 0) {
128+
// Root node has no siblings
129+
List.empty
130+
} else {
131+
// Get parent ordinal
132+
val parent = (ordinal - 1) / nsWidth
133+
// Get all children of parent (siblings including self) and exclude self
134+
childrenOf(parent).filter(_ != ordinal)
135+
}
103136
}

benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/NamespaceActions.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ case class NamespaceActions(
173173
* There is no limit to the number of users that can fetch namespaces concurrently.
174174
*/
175175
val fetchNamespace: ChainBuilder = exec(
176-
http("Fetch Namespace")
176+
http("Fetch single namespace")
177177
.get("/api/catalog/v1/#{catalogName}/namespaces/#{namespaceMultipartPath}")
178178
.header("Authorization", "Bearer #{accessToken}")
179179
.check(status.is(200))
@@ -206,15 +206,15 @@ case class NamespaceActions(
206206
* structure.
207207
*/
208208
val fetchAllChildrenNamespaces: ChainBuilder = exec(
209-
http("Fetch all Namespaces under specific parent")
209+
http("Fetch child namespaces")
210210
.get("/api/catalog/v1/#{catalogName}/namespaces?parent=#{namespaceMultipartPath}")
211211
.header("Authorization", "Bearer #{accessToken}")
212212
.check(status.is(200))
213213
)
214214

215215
val updateNamespaceProperties: ChainBuilder =
216-
retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update namespace properties")(
217-
http("Update Namespace Properties")
216+
retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update namespace")(
217+
http("Update namespace")
218218
.post("/api/catalog/v1/#{catalogName}/namespaces/#{namespaceMultipartPath}/properties")
219219
.header("Authorization", "Bearer #{accessToken}")
220220
.header("Content-Type", "application/json")

benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/TableActions.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ case class TableActions(
149149
*
150150
* There is no limit to the number of users that can create tables concurrently.
151151
*/
152-
val createTable: ChainBuilder = retryOnHttpStatus(maxRetries, retryableHttpCodes, "Create table")(
152+
val createTable: ChainBuilder = retryOnHttpStatus(maxRetries, retryableHttpCodes, "Create Table")(
153153
http("Create Table")
154154
.post("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/tables")
155155
.header("Authorization", "Bearer #{accessToken}")
@@ -181,7 +181,7 @@ case class TableActions(
181181
* There is no limit to the number of users that can fetch tables concurrently.
182182
*/
183183
val fetchTable: ChainBuilder = exec(
184-
http("Fetch Table")
184+
http("Fetch single Table")
185185
.get("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/tables/#{tableName}")
186186
.header("Authorization", "Bearer #{accessToken}")
187187
.check(status.is(200))
@@ -209,7 +209,7 @@ case class TableActions(
209209
* given namespace, supporting bulk retrieval of table metadata.
210210
*/
211211
val fetchAllTables: ChainBuilder = exec(
212-
http("Fetch all Tables under parent namespace")
212+
http("Fetch children Tables")
213213
.get("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/tables")
214214
.header("Authorization", "Bearer #{accessToken}")
215215
.check(status.is(200))
@@ -222,8 +222,8 @@ case class TableActions(
222222
* There is no limit to the number of users that can update table properties concurrently.
223223
*/
224224
val updateTable: ChainBuilder =
225-
retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update table metadata")(
226-
http("Update table metadata")
225+
retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update Table")(
226+
http("Update Table")
227227
.post("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/tables/#{tableName}")
228228
.header("Authorization", "Bearer #{accessToken}")
229229
.header("Content-Type", "application/json")

benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/ViewActions.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ case class ViewActions(
134134
)
135135
}
136136

137-
val createView: ChainBuilder = retryOnHttpStatus(maxRetries, retryableHttpCodes, "Create view")(
137+
val createView: ChainBuilder = retryOnHttpStatus(maxRetries, retryableHttpCodes, "Create View")(
138138
http("Create View")
139139
.post("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/views")
140140
.header("Authorization", "Bearer #{accessToken}")
@@ -171,7 +171,7 @@ case class ViewActions(
171171
)
172172

173173
val fetchView: ChainBuilder = exec(
174-
http("Fetch View")
174+
http("Fetch single View")
175175
.get("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/views/#{viewName}")
176176
.header("Authorization", "Bearer #{accessToken}")
177177
.check(status.is(200))
@@ -195,7 +195,7 @@ case class ViewActions(
195195
)
196196

197197
val fetchAllViews: ChainBuilder = exec(
198-
http("Fetch all Views under parent namespace")
198+
http("Fetch children Views")
199199
.get("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/views")
200200
.header("Authorization", "Bearer #{accessToken}")
201201
.check(status.is(200))
@@ -208,8 +208,8 @@ case class ViewActions(
208208
* There is no limit to the number of users that can update table properties concurrently.
209209
*/
210210
val updateView: ChainBuilder =
211-
retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update View metadata")(
212-
http("Update View metadata")
211+
retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update View")(
212+
http("Update View")
213213
.post("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/views/#{viewName}")
214214
.header("Authorization", "Bearer #{accessToken}")
215215
.header("Content-Type", "application/json")

benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/simulations/ReadUpdateTreeDataset.scala

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ class ReadUpdateTreeDataset extends Simulation {
5454
// --------------------------------------------------------------------------------
5555
// Helper values
5656
// --------------------------------------------------------------------------------
57-
private val numNamespaces: Int = dp.nAryTree.numberOfNodes
5857
private val accessToken: AtomicReference[String] = new AtomicReference()
5958
private val shouldRefreshToken: AtomicBoolean = new AtomicBoolean(true)
6059

@@ -64,6 +63,21 @@ class ReadUpdateTreeDataset extends Simulation {
6463
private val tblActions = TableActions(dp, wp, accessToken)
6564
private val viewActions = ViewActions(dp, wp, accessToken)
6665

66+
private val nsListFeeder = new CircularIterator(nsActions.namespaceIdentityFeeder)
67+
private val nsExistsFeeder = new CircularIterator(nsActions.namespaceIdentityFeeder)
68+
private val nsFetchFeeder = new CircularIterator(nsActions.namespaceFetchFeeder)
69+
private val nsUpdateFeeder = nsActions.namespacePropertiesUpdateFeeder()
70+
71+
private val tblListFeeder = new CircularIterator(tblActions.tableIdentityFeeder)
72+
private val tblExistsFeeder = new CircularIterator(tblActions.tableIdentityFeeder)
73+
private val tblFetchFeeder = new CircularIterator(tblActions.tableFetchFeeder)
74+
private val tblUpdateFeeder = tblActions.propertyUpdateFeeder()
75+
76+
private val viewListFeeder = new CircularIterator(viewActions.viewIdentityFeeder)
77+
private val viewExistsFeeder = new CircularIterator(viewActions.viewIdentityFeeder)
78+
private val viewFetchFeeder = new CircularIterator(viewActions.viewFetchFeeder)
79+
private val viewUpdateFeeder = viewActions.propertyUpdateFeeder()
80+
6781
// --------------------------------------------------------------------------------
6882
// Authentication related workloads:
6983
// * Authenticate and store the access token for later use every minute
@@ -91,21 +105,6 @@ class ReadUpdateTreeDataset extends Simulation {
91105
session
92106
}
93107

94-
private val nsListFeeder = new CircularIterator(nsActions.namespaceIdentityFeeder)
95-
private val nsExistsFeeder = new CircularIterator(nsActions.namespaceIdentityFeeder)
96-
private val nsFetchFeeder = new CircularIterator(nsActions.namespaceFetchFeeder)
97-
private val nsUpdateFeeder = nsActions.namespacePropertiesUpdateFeeder()
98-
99-
private val tblListFeeder = new CircularIterator(tblActions.tableIdentityFeeder)
100-
private val tblExistsFeeder = new CircularIterator(tblActions.tableIdentityFeeder)
101-
private val tblFetchFeeder = new CircularIterator(tblActions.tableFetchFeeder)
102-
private val tblUpdateFeeder = tblActions.propertyUpdateFeeder()
103-
104-
private val viewListFeeder = new CircularIterator(viewActions.viewIdentityFeeder)
105-
private val viewExistsFeeder = new CircularIterator(viewActions.viewIdentityFeeder)
106-
private val viewFetchFeeder = new CircularIterator(viewActions.viewFetchFeeder)
107-
private val viewUpdateFeeder = viewActions.propertyUpdateFeeder()
108-
109108
// --------------------------------------------------------------------------------
110109
// Workload: Randomly read and write entities
111110
// --------------------------------------------------------------------------------

0 commit comments

Comments
 (0)