This is an automated email from the ASF dual-hosted git repository.
pingtimeout pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris-tools.git
The following commit(s) were added to refs/heads/main by this push:
new 6c2d4d4 Small Benchmarks improvements (#25)
6c2d4d4 is described below
commit 6c2d4d45f44b60a06eeca549bc80f7205cb082e0
Author: Pierre Laporte <[email protected]>
AuthorDate: Thu Jul 10 09:28:56 2025 +0200
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.
---
.../polaris/benchmarks/NAryTreeBuilder.scala | 33 ++++++++++++++++++++++
.../benchmarks/actions/NamespaceActions.scala | 8 +++---
.../polaris/benchmarks/actions/TableActions.scala | 10 +++----
.../polaris/benchmarks/actions/ViewActions.scala | 10 +++----
.../simulations/ReadUpdateTreeDataset.scala | 31 ++++++++++----------
5 files changed, 62 insertions(+), 30 deletions(-)
diff --git
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/NAryTreeBuilder.scala
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/NAryTreeBuilder.scala
index 326ef6d..582b5de 100644
---
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/NAryTreeBuilder.scala
+++
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/NAryTreeBuilder.scala
@@ -47,6 +47,22 @@ case class NAryTreeBuilder(nsWidth: Int, nsDepth: Int) {
pathToRoot(parent, ordinal :: acc)
}
+ /**
+ * Computes the ordinals of all child nodes for a given node.
+ *
+ * @param ordinal the ordinal of the parent node
+ * @return a list of ordinals representing the child nodes
+ */
+ def childrenOf(ordinal: Int): List[Int] =
+ if (depthOf(ordinal) >= nsDepth - 1) {
+ // Node is a leaf, has no children
+ List.empty
+ } else {
+ // For a node with ordinal p, its children have ordinals: p*nsWidth + 1,
p*nsWidth + 2, ..., p*nsWidth + nsWidth
+ val firstChild = ordinal * nsWidth + 1
+ (firstChild until firstChild + nsWidth).toList
+ }
+
/**
* Calculates the depth of a node in the n-ary tree based on its ordinal.
*
@@ -100,4 +116,21 @@ case class NAryTreeBuilder(nsWidth: Int, nsDepth: Int) {
val lastLevel = nsDepth - 1
math.pow(nsWidth, lastLevel).toInt
}
+
+ /**
+ * Computes the ordinals of all sibling nodes for a given node.
+ *
+ * @param ordinal the ordinal of the node
+ * @return a list of ordinals representing the sibling nodes (excluding the
node itself)
+ */
+ def siblingsOf(ordinal: Int): List[Int] =
+ if (ordinal == 0) {
+ // Root node has no siblings
+ List.empty
+ } else {
+ // Get parent ordinal
+ val parent = (ordinal - 1) / nsWidth
+ // Get all children of parent (siblings including self) and exclude self
+ childrenOf(parent).filter(_ != ordinal)
+ }
}
diff --git
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/NamespaceActions.scala
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/NamespaceActions.scala
index 7a5f5f0..1fedc70 100644
---
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/NamespaceActions.scala
+++
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/NamespaceActions.scala
@@ -173,7 +173,7 @@ case class NamespaceActions(
* There is no limit to the number of users that can fetch namespaces
concurrently.
*/
val fetchNamespace: ChainBuilder = exec(
- http("Fetch Namespace")
+ http("Fetch single namespace")
.get("/api/catalog/v1/#{catalogName}/namespaces/#{namespaceMultipartPath}")
.header("Authorization", "Bearer #{accessToken}")
.check(status.is(200))
@@ -206,15 +206,15 @@ case class NamespaceActions(
* structure.
*/
val fetchAllChildrenNamespaces: ChainBuilder = exec(
- http("Fetch all Namespaces under specific parent")
+ http("Fetch child namespaces")
.get("/api/catalog/v1/#{catalogName}/namespaces?parent=#{namespaceMultipartPath}")
.header("Authorization", "Bearer #{accessToken}")
.check(status.is(200))
)
val updateNamespaceProperties: ChainBuilder =
- retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update namespace
properties")(
- http("Update Namespace Properties")
+ retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update namespace")(
+ http("Update namespace")
.post("/api/catalog/v1/#{catalogName}/namespaces/#{namespaceMultipartPath}/properties")
.header("Authorization", "Bearer #{accessToken}")
.header("Content-Type", "application/json")
diff --git
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/TableActions.scala
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/TableActions.scala
index 1d5b951..67e0ac0 100644
---
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/TableActions.scala
+++
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/TableActions.scala
@@ -149,7 +149,7 @@ case class TableActions(
*
* There is no limit to the number of users that can create tables
concurrently.
*/
- val createTable: ChainBuilder = retryOnHttpStatus(maxRetries,
retryableHttpCodes, "Create table")(
+ val createTable: ChainBuilder = retryOnHttpStatus(maxRetries,
retryableHttpCodes, "Create Table")(
http("Create Table")
.post("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/tables")
.header("Authorization", "Bearer #{accessToken}")
@@ -181,7 +181,7 @@ case class TableActions(
* There is no limit to the number of users that can fetch tables
concurrently.
*/
val fetchTable: ChainBuilder = exec(
- http("Fetch Table")
+ http("Fetch single Table")
.get("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/tables/#{tableName}")
.header("Authorization", "Bearer #{accessToken}")
.check(status.is(200))
@@ -209,7 +209,7 @@ case class TableActions(
* given namespace, supporting bulk retrieval of table metadata.
*/
val fetchAllTables: ChainBuilder = exec(
- http("Fetch all Tables under parent namespace")
+ http("Fetch children Tables")
.get("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/tables")
.header("Authorization", "Bearer #{accessToken}")
.check(status.is(200))
@@ -222,8 +222,8 @@ case class TableActions(
* There is no limit to the number of users that can update table properties
concurrently.
*/
val updateTable: ChainBuilder =
- retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update table metadata")(
- http("Update table metadata")
+ retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update Table")(
+ http("Update Table")
.post("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/tables/#{tableName}")
.header("Authorization", "Bearer #{accessToken}")
.header("Content-Type", "application/json")
diff --git
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/ViewActions.scala
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/ViewActions.scala
index 14bf698..99ff175 100644
---
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/ViewActions.scala
+++
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/actions/ViewActions.scala
@@ -134,7 +134,7 @@ case class ViewActions(
)
}
- val createView: ChainBuilder = retryOnHttpStatus(maxRetries,
retryableHttpCodes, "Create view")(
+ val createView: ChainBuilder = retryOnHttpStatus(maxRetries,
retryableHttpCodes, "Create View")(
http("Create View")
.post("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/views")
.header("Authorization", "Bearer #{accessToken}")
@@ -171,7 +171,7 @@ case class ViewActions(
)
val fetchView: ChainBuilder = exec(
- http("Fetch View")
+ http("Fetch single View")
.get("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/views/#{viewName}")
.header("Authorization", "Bearer #{accessToken}")
.check(status.is(200))
@@ -195,7 +195,7 @@ case class ViewActions(
)
val fetchAllViews: ChainBuilder = exec(
- http("Fetch all Views under parent namespace")
+ http("Fetch children Views")
.get("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/views")
.header("Authorization", "Bearer #{accessToken}")
.check(status.is(200))
@@ -208,8 +208,8 @@ case class ViewActions(
* There is no limit to the number of users that can update table properties
concurrently.
*/
val updateView: ChainBuilder =
- retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update View metadata")(
- http("Update View metadata")
+ retryOnHttpStatus(maxRetries, retryableHttpCodes, "Update View")(
+ http("Update View")
.post("/api/catalog/v1/#{catalogName}/namespaces/#{multipartNamespace}/views/#{viewName}")
.header("Authorization", "Bearer #{accessToken}")
.header("Content-Type", "application/json")
diff --git
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/simulations/ReadUpdateTreeDataset.scala
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/simulations/ReadUpdateTreeDataset.scala
index 4d5ebb9..2304920 100644
---
a/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/simulations/ReadUpdateTreeDataset.scala
+++
b/benchmarks/src/gatling/scala/org/apache/polaris/benchmarks/simulations/ReadUpdateTreeDataset.scala
@@ -54,7 +54,6 @@ class ReadUpdateTreeDataset extends Simulation {
//
--------------------------------------------------------------------------------
// Helper values
//
--------------------------------------------------------------------------------
- private val numNamespaces: Int = dp.nAryTree.numberOfNodes
private val accessToken: AtomicReference[String] = new AtomicReference()
private val shouldRefreshToken: AtomicBoolean = new AtomicBoolean(true)
@@ -64,6 +63,21 @@ class ReadUpdateTreeDataset extends Simulation {
private val tblActions = TableActions(dp, wp, accessToken)
private val viewActions = ViewActions(dp, wp, accessToken)
+ private val nsListFeeder = new
CircularIterator(nsActions.namespaceIdentityFeeder)
+ private val nsExistsFeeder = new
CircularIterator(nsActions.namespaceIdentityFeeder)
+ private val nsFetchFeeder = new
CircularIterator(nsActions.namespaceFetchFeeder)
+ private val nsUpdateFeeder = nsActions.namespacePropertiesUpdateFeeder()
+
+ private val tblListFeeder = new
CircularIterator(tblActions.tableIdentityFeeder)
+ private val tblExistsFeeder = new
CircularIterator(tblActions.tableIdentityFeeder)
+ private val tblFetchFeeder = new
CircularIterator(tblActions.tableFetchFeeder)
+ private val tblUpdateFeeder = tblActions.propertyUpdateFeeder()
+
+ private val viewListFeeder = new
CircularIterator(viewActions.viewIdentityFeeder)
+ private val viewExistsFeeder = new
CircularIterator(viewActions.viewIdentityFeeder)
+ private val viewFetchFeeder = new
CircularIterator(viewActions.viewFetchFeeder)
+ private val viewUpdateFeeder = viewActions.propertyUpdateFeeder()
+
//
--------------------------------------------------------------------------------
// Authentication related workloads:
// * Authenticate and store the access token for later use every minute
@@ -91,21 +105,6 @@ class ReadUpdateTreeDataset extends Simulation {
session
}
- private val nsListFeeder = new
CircularIterator(nsActions.namespaceIdentityFeeder)
- private val nsExistsFeeder = new
CircularIterator(nsActions.namespaceIdentityFeeder)
- private val nsFetchFeeder = new
CircularIterator(nsActions.namespaceFetchFeeder)
- private val nsUpdateFeeder = nsActions.namespacePropertiesUpdateFeeder()
-
- private val tblListFeeder = new
CircularIterator(tblActions.tableIdentityFeeder)
- private val tblExistsFeeder = new
CircularIterator(tblActions.tableIdentityFeeder)
- private val tblFetchFeeder = new
CircularIterator(tblActions.tableFetchFeeder)
- private val tblUpdateFeeder = tblActions.propertyUpdateFeeder()
-
- private val viewListFeeder = new
CircularIterator(viewActions.viewIdentityFeeder)
- private val viewExistsFeeder = new
CircularIterator(viewActions.viewIdentityFeeder)
- private val viewFetchFeeder = new
CircularIterator(viewActions.viewFetchFeeder)
- private val viewUpdateFeeder = viewActions.propertyUpdateFeeder()
-
//
--------------------------------------------------------------------------------
// Workload: Randomly read and write entities
//
--------------------------------------------------------------------------------