mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
Merge remote-tracking branch 'origin/main' into driver/weaviate
This commit is contained in:
commit
c6d165046c
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@ -12,7 +12,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
name: checkout nosqlbench
|
name: checkout nosqlbench
|
||||||
@ -25,6 +25,9 @@ jobs:
|
|||||||
java-package: jdk
|
java-package: jdk
|
||||||
java-version: '21'
|
java-version: '21'
|
||||||
|
|
||||||
|
- name: install fuse2
|
||||||
|
run: sudo apt install libfuse2
|
||||||
|
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
@ -74,7 +77,7 @@ jobs:
|
|||||||
|
|
||||||
builddocs:
|
builddocs:
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
if: ${{ github.repository == 'nosqlbench/nosqlbench' && github.event_name == 'push' && github.ref_name == 'main' }}
|
if: ${{ github.repository == 'nosqlbench/nosqlbench' && github.event_name == 'push' && github.ref_name == 'main' }}
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
|
7
.github/workflows/preview.yml
vendored
7
.github/workflows/preview.yml
vendored
@ -15,7 +15,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
preview-build:
|
preview-build:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
outputs:
|
outputs:
|
||||||
preview_version: ${{ steps.versions.outputs.PREVIEW_VERSION }}
|
preview_version: ${{ steps.versions.outputs.PREVIEW_VERSION }}
|
||||||
docker_tags: ${{ steps.versions.outputs.DOCKER_TAGS }}
|
docker_tags: ${{ steps.versions.outputs.DOCKER_TAGS }}
|
||||||
@ -46,6 +46,9 @@ jobs:
|
|||||||
docker rmi $(docker image ls -aq)
|
docker rmi $(docker image ls -aq)
|
||||||
df -h
|
df -h
|
||||||
|
|
||||||
|
- name: install fuse2
|
||||||
|
run: sudo apt install libfuse2
|
||||||
|
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
@ -204,7 +207,7 @@ jobs:
|
|||||||
|
|
||||||
preview-docs:
|
preview-docs:
|
||||||
needs: preview-build
|
needs: preview-build
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: import env vars
|
- name: import env vars
|
||||||
run: |
|
run: |
|
||||||
|
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@ -15,7 +15,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-build:
|
release-build:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: checkout repo
|
- name: checkout repo
|
||||||
@ -43,6 +43,9 @@ jobs:
|
|||||||
docker rmi $(docker image ls -aq)
|
docker rmi $(docker image ls -aq)
|
||||||
df -h
|
df -h
|
||||||
|
|
||||||
|
- name: install fuse2
|
||||||
|
run: sudo apt install libfuse2
|
||||||
|
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
@ -186,7 +189,7 @@ jobs:
|
|||||||
|
|
||||||
# javadocs:
|
# javadocs:
|
||||||
# needs: release
|
# needs: release
|
||||||
# runs-on: ubuntu-20.04
|
# runs-on: ubuntu-22.04
|
||||||
# steps:
|
# steps:
|
||||||
# - name: set git username
|
# - name: set git username
|
||||||
# run: git config --global user.email "${{ secrets.NBDROID_EMAIL }}"
|
# run: git config --global user.email "${{ secrets.NBDROID_EMAIL }}"
|
||||||
@ -210,7 +213,7 @@ jobs:
|
|||||||
#
|
#
|
||||||
# docs:
|
# docs:
|
||||||
# needs: release
|
# needs: release
|
||||||
# runs-on: ubuntu-20.04
|
# runs-on: ubuntu-22.04
|
||||||
# steps:
|
# steps:
|
||||||
#
|
#
|
||||||
# - name: set git username
|
# - name: set git username
|
||||||
|
@ -573,6 +573,9 @@
|
|||||||
</includes>
|
</includes>
|
||||||
<useSystemClassLoader>false
|
<useSystemClassLoader>false
|
||||||
</useSystemClassLoader> <!-- fixes reflection tests -->
|
</useSystemClassLoader> <!-- fixes reflection tests -->
|
||||||
|
<environmentVariables>
|
||||||
|
<TEST_ENV_VAR>value</TEST_ENV_VAR>
|
||||||
|
</environmentVariables>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ public class CGWorkloadExporter implements BundledApp {
|
|||||||
private String namingTemplate;
|
private String namingTemplate;
|
||||||
private double partitionMultiplier;
|
private double partitionMultiplier;
|
||||||
private int quantizerDigits;
|
private int quantizerDigits;
|
||||||
|
private boolean enableIfExists = true;
|
||||||
private Map<String, List<String>> blockplan = Map.of();
|
private Map<String, List<String>> blockplan = Map.of();
|
||||||
|
|
||||||
private final Map<String, Double> timeouts = new HashMap<String, Double>(Map.of(
|
private final Map<String, Double> timeouts = new HashMap<String, Double>(Map.of(
|
||||||
@ -163,6 +164,9 @@ public class CGWorkloadExporter implements BundledApp {
|
|||||||
configureTimeouts(cfgmap.get("timeouts"));
|
configureTimeouts(cfgmap.get("timeouts"));
|
||||||
configureBlocks(cfgmap.get("blockplan"));
|
configureBlocks(cfgmap.get("blockplan"));
|
||||||
configureQuantizerDigits(cfgmap.get("quantizer_digits"));
|
configureQuantizerDigits(cfgmap.get("quantizer_digits"));
|
||||||
|
if (cfgmap.get("enable_if_exists").equals(false)) {
|
||||||
|
enableIfExists = false;
|
||||||
|
}
|
||||||
|
|
||||||
this.model = CqlModelParser.parse(ddl, srcpath);
|
this.model = CqlModelParser.parse(ddl, srcpath);
|
||||||
List<String> errorlist = model.getReferenceErrors();
|
List<String> errorlist = model.getReferenceErrors();
|
||||||
@ -639,7 +643,7 @@ public class CGWorkloadExporter implements BundledApp {
|
|||||||
ops.put(
|
ops.put(
|
||||||
namer.nameFor(table, "optype", "drop", "blockname", blockname),
|
namer.nameFor(table, "optype", "drop", "blockname", blockname),
|
||||||
Map.of(
|
Map.of(
|
||||||
"simple", "drop table if exists " + table.getFullName() + ";",
|
"simple", (enableIfExists ? "drop table if exists " : "drop table ") + table.getFullName() + ";",
|
||||||
"timeout", timeouts.get("drop")
|
"timeout", timeouts.get("drop")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -655,7 +659,7 @@ public class CGWorkloadExporter implements BundledApp {
|
|||||||
ops.put(
|
ops.put(
|
||||||
namer.nameFor(type, "optype", "drop-type", "blockname", blockname),
|
namer.nameFor(type, "optype", "drop-type", "blockname", blockname),
|
||||||
Map.of(
|
Map.of(
|
||||||
"simple", "drop type if exists " + type.getKeyspace() + "." + type.getName() + ";",
|
"simple", (enableIfExists ? "drop type if exists " : "drop type ") + "." + type.getName() + ";",
|
||||||
"timeout", timeouts.get("drop")
|
"timeout", timeouts.get("drop")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -671,7 +675,7 @@ public class CGWorkloadExporter implements BundledApp {
|
|||||||
ops.put(
|
ops.put(
|
||||||
namer.nameFor(type, "optype", "drop-keyspace", "blockname", blockname),
|
namer.nameFor(type, "optype", "drop-keyspace", "blockname", blockname),
|
||||||
Map.of(
|
Map.of(
|
||||||
"simple", "drop keyspace if exists " + type.getKeyspace() + ";",
|
"simple", (enableIfExists ? "drop keyspace if exists " : "drop keyspace ") + type.getKeyspace() + ";",
|
||||||
"timeout", timeouts.get("drop")
|
"timeout", timeouts.get("drop")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -736,9 +740,10 @@ public class CGWorkloadExporter implements BundledApp {
|
|||||||
|
|
||||||
private String genKeyspaceDDL(CqlKeyspaceDef keyspace) {
|
private String genKeyspaceDDL(CqlKeyspaceDef keyspace) {
|
||||||
return """
|
return """
|
||||||
create keyspace KEYSPACE
|
create keyspace IF_NOT_EXISTS KEYSPACE
|
||||||
with replication = {REPLICATION}DURABLEWRITES?;
|
with replication = {REPLICATION}DURABLEWRITES?;
|
||||||
"""
|
"""
|
||||||
|
.replace("IF_NOT_EXISTS", enableIfExists ? "if not exists" : "")
|
||||||
.replace("KEYSPACE", keyspace.getName())
|
.replace("KEYSPACE", keyspace.getName())
|
||||||
.replace("REPLICATION", keyspace.getReplicationData())
|
.replace("REPLICATION", keyspace.getReplicationData())
|
||||||
.replace("DURABLEWRITES?", keyspace.isDurableWrites() ? "" : "\n and durable writes = false")
|
.replace("DURABLEWRITES?", keyspace.isDurableWrites() ? "" : "\n and durable writes = false")
|
||||||
@ -766,10 +771,11 @@ public class CGWorkloadExporter implements BundledApp {
|
|||||||
|
|
||||||
private String genTypeDDL(CqlType type) {
|
private String genTypeDDL(CqlType type) {
|
||||||
return """
|
return """
|
||||||
create type KEYSPACE.TYPENAME (
|
create type IF_NOT_EXISTS KEYSPACE.TYPENAME (
|
||||||
TYPEDEF
|
TYPEDEF
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
|
.replace("IF_NOT_EXISTS", enableIfExists ? "if not exists" : "")
|
||||||
.replace("KEYSPACE", type.getKeyspace().getName())
|
.replace("KEYSPACE", type.getKeyspace().getName())
|
||||||
.replace("TYPENAME", type.getName())
|
.replace("TYPENAME", type.getName())
|
||||||
.replace("TYPEDEF", type.getColumnDefs().stream()
|
.replace("TYPEDEF", type.getColumnDefs().stream()
|
||||||
@ -782,11 +788,12 @@ public class CGWorkloadExporter implements BundledApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return """
|
return """
|
||||||
create table if not exists KEYSPACE.TABLE (
|
create table IF_NOT_EXISTS KEYSPACE.TABLE (
|
||||||
COLUMN_DEFS,
|
COLUMN_DEFS,
|
||||||
primary key (PRIMARYKEY)
|
primary key (PRIMARYKEY)
|
||||||
)CLUSTERING;
|
)CLUSTERING;
|
||||||
"""
|
"""
|
||||||
|
.replace("IF_NOT_EXISTS", enableIfExists ? "if not exists" : "")
|
||||||
.replace("KEYSPACE", cqltable.getKeyspace().getName())
|
.replace("KEYSPACE", cqltable.getKeyspace().getName())
|
||||||
.replace("TABLE", cqltable.getName())
|
.replace("TABLE", cqltable.getName())
|
||||||
.replace("COLUMN_DEFS", genTableColumnDDL(cqltable))
|
.replace("COLUMN_DEFS", genTableColumnDDL(cqltable))
|
||||||
|
@ -10,7 +10,7 @@ scenarios:
|
|||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||||
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||||
astra:
|
astra:
|
||||||
schema: run driver=cql tags==block:schema-astra threads==1 cycles==UNDEF
|
schema: run driver=cql tags==block:schema_astra threads==1 cycles==UNDEF
|
||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||||
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||||
basic_check:
|
basic_check:
|
||||||
|
@ -14,7 +14,7 @@ scenarios:
|
|||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||||
main: run driver=cql tags=='block:main-.*' cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
main: run driver=cql tags=='block:main-.*' cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||||
astra:
|
astra:
|
||||||
schema: run driver=cql tags==block:schema-astra threads==1 cycles==UNDEF
|
schema: run driver=cql tags==block:schema_astra threads==1 cycles==UNDEF
|
||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||||
main: run driver=cql tags=='block:main-.*' cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
main: run driver=cql tags=='block:main-.*' cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||||
basic_check:
|
basic_check:
|
||||||
|
@ -11,7 +11,7 @@ scenarios:
|
|||||||
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10) threads=auto
|
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10) threads=auto
|
||||||
# rampdown: run driver=cql tags==block:rampdown threads==1 cycles==UNDEF
|
# rampdown: run driver=cql tags==block:rampdown threads==1 cycles==UNDEF
|
||||||
astra:
|
astra:
|
||||||
schema: run driver=cql tags==block:schema-astra threads==1 cycles==UNDEF
|
schema: run driver=cql tags==block:schema_astra threads==1 cycles==UNDEF
|
||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10) threads=auto
|
||||||
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10) threads=auto
|
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10) threads=auto
|
||||||
basic_check:
|
basic_check:
|
||||||
|
@ -7,7 +7,7 @@ scenarios:
|
|||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||||
main: run driver=cql tags==block:main-*.* cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
main: run driver=cql tags==block:main-*.* cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||||
astra:
|
astra:
|
||||||
schema: run driver=cql tags==block:schema-astra threads==1 cycles==UNDEF
|
schema: run driver=cql tags==block:schema_astra threads==1 cycles==UNDEF
|
||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||||
main: run driver=cql tags==block:main-*.* cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
main: run driver=cql tags==block:main-*.* cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||||
basic_check:
|
basic_check:
|
||||||
|
@ -31,7 +31,7 @@ scenarios:
|
|||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,100) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,100) threads=auto
|
||||||
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,100) threads=auto
|
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,100) threads=auto
|
||||||
astra:
|
astra:
|
||||||
schema: run driver=cql tags==block:schema-astra threads==1 cycles==UNDEF
|
schema: run driver=cql tags==block:schema_astra threads==1 cycles==UNDEF
|
||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,100) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,100) threads=auto
|
||||||
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,100) threads=auto
|
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,100) threads=auto
|
||||||
basic_check:
|
basic_check:
|
||||||
|
@ -10,7 +10,7 @@ scenarios:
|
|||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||||
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||||
astra:
|
astra:
|
||||||
schema: run driver=cql tags==block:schema-astra threads==1 cycles==UNDEF
|
schema: run driver=cql tags==block:schema_astra threads==1 cycles==UNDEF
|
||||||
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
rampup: run driver=cql tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||||
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
main: run driver=cql tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||||
basic_check:
|
basic_check:
|
||||||
|
@ -145,6 +145,6 @@ blockplan:
|
|||||||
# not needed when tags=block:'main.*'
|
# not needed when tags=block:'main.*'
|
||||||
# main: insert, select, scan-10, update
|
# main: insert, select, scan-10, update
|
||||||
|
|
||||||
|
# Configuration option for adding 'IF NOT EXISTS' or 'IF EXISTS' in all generated DDL statements
|
||||||
|
enable_if_exists: true
|
||||||
|
|
||||||
|
@ -66,7 +66,10 @@ public class DataApiDeleteOneOpDispenser extends DataApiOpDispenser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private float[] getVectorFromOp(ParsedOp op, long l) {
|
private float[] getVectorFromOp(ParsedOp op, long l) {
|
||||||
return getVectorValues(op.get("vector", l));
|
if (op.isDefined("vector")) {
|
||||||
|
return getVectorValues(op.get("vector", l));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
min_version: "5.21.0"
|
||||||
|
|
||||||
|
description: |
|
||||||
|
TBD, similar to find_one_and_delete.yaml
|
@ -6,4 +6,4 @@ blocks:
|
|||||||
list_collection_names:
|
list_collection_names:
|
||||||
ops:
|
ops:
|
||||||
op1:
|
op1:
|
||||||
list_collection_names:
|
list_collection_names: TBD
|
||||||
|
@ -6,4 +6,4 @@ blocks:
|
|||||||
list_collections:
|
list_collections:
|
||||||
ops:
|
ops:
|
||||||
op1:
|
op1:
|
||||||
list_collections:
|
list_collections: TBD
|
||||||
|
@ -140,7 +140,7 @@ public class RawOpDef extends RawOpFields {
|
|||||||
if (v == null) {
|
if (v == null) {
|
||||||
throw new OpConfigError("A map key '" + k.toString() + "' with a null value was encountered. This is not" +
|
throw new OpConfigError("A map key '" + k.toString() + "' with a null value was encountered. This is not" +
|
||||||
" allowed, and may be the result of using an unquoted binding, like {" + k + "}. You can simply wrap this in quotes" +
|
" allowed, and may be the result of using an unquoted binding, like {" + k + "}. You can simply wrap this in quotes" +
|
||||||
" like \"{"+ k +"\"} to avoid interpreting this as a JSON map." +
|
" like \"{"+ k +"}\" to avoid interpreting this as a JSON map." +
|
||||||
(path.size()>0 ? String.join(".",path):""));
|
(path.size()>0 ? String.join(".",path):""));
|
||||||
} else {
|
} else {
|
||||||
if (v instanceof Map) {
|
if (v instanceof Map) {
|
||||||
|
@ -53,7 +53,7 @@ public class FieldDestructuringMapper implements Function<Map<String, Object>, M
|
|||||||
return stringObjectMap;
|
return stringObjectMap;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("During op mapping, can't parse something that is not a CharSequence: '" + fieldname + "' (type is " + o.getClass().getCanonicalName() + ")");
|
throw new RuntimeException("During op mapping, can't parse something that is not a CharSequence: '" + fieldname + "' (type is " + o.getClass().getCanonicalName() + ") (value is:" + o.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return stringObjectMap;
|
return stringObjectMap;
|
||||||
|
@ -99,12 +99,37 @@ public class NBCreators {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public WindowSummaryGauge windowSummaryGauge(
|
||||||
|
String name,
|
||||||
|
int window,
|
||||||
|
List<String> statspecs,
|
||||||
|
MetricCategory category,
|
||||||
|
String description
|
||||||
|
) {
|
||||||
|
List<WindowSummaryGauge.Stat> stats =
|
||||||
|
statspecs.stream().map(WindowSummaryGauge.Stat::valueOf).toList();
|
||||||
|
DoubleSummaryStatistics reservoir = new DoubleSummaryStatistics();
|
||||||
|
WindowSummaryGauge anyGauge = null;
|
||||||
|
for (WindowSummaryGauge.Stat stat : stats) {
|
||||||
|
anyGauge = new WindowSummaryGauge(
|
||||||
|
window,
|
||||||
|
base.getLabels().and(NBLabels.forKV("name", name+"_w"+window, "stat", stat)),
|
||||||
|
stat,
|
||||||
|
description,
|
||||||
|
category
|
||||||
|
);
|
||||||
|
base.addComponentMetric(anyGauge, category, description);
|
||||||
|
}
|
||||||
|
return anyGauge;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public DoubleSummaryGauge summaryGauge(String name, List<String> statspecs, MetricCategory category, String description) {
|
public DoubleSummaryGauge summaryGauge(String name, List<String> statspecs, MetricCategory category, String description) {
|
||||||
List<DoubleSummaryGauge.Stat> stats = statspecs.stream().map(DoubleSummaryGauge.Stat::valueOf).toList();
|
List<DoubleSummaryGauge.Stat> stats = statspecs.stream().map(DoubleSummaryGauge.Stat::valueOf).toList();
|
||||||
DoubleSummaryStatistics reservoir = new DoubleSummaryStatistics();
|
DoubleSummaryStatistics reservoir = new DoubleSummaryStatistics();
|
||||||
DoubleSummaryGauge anyGauge = null;
|
DoubleSummaryGauge anyGauge = null;
|
||||||
for (DoubleSummaryGauge.Stat stat : stats) {
|
for (DoubleSummaryGauge.Stat stat : stats) {
|
||||||
anyGauge = new DoubleSummaryGauge(base.getLabels().and(NBLabels.forKV("name",name,"stat", stat)), stat, reservoir, description, category);
|
anyGauge = new DoubleSummaryGauge(base.getLabels().and(NBLabels.forKV("name", name, "stat", stat)), stat, reservoir, description, category);
|
||||||
base.addComponentMetric(anyGauge, category, description);
|
base.addComponentMetric(anyGauge, category, description);
|
||||||
}
|
}
|
||||||
return anyGauge;
|
return anyGauge;
|
||||||
@ -113,6 +138,7 @@ public class NBCreators {
|
|||||||
public NBMetricHistogram histogram(String metricFamilyName, MetricCategory category, String description) {
|
public NBMetricHistogram histogram(String metricFamilyName, MetricCategory category, String description) {
|
||||||
return histogram(metricFamilyName,4, category, description);
|
return histogram(metricFamilyName,4, category, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBMetricHistogram histogram(String metricFamilyName, int hdrdigits, MetricCategory category, String description) {
|
public NBMetricHistogram histogram(String metricFamilyName, int hdrdigits, MetricCategory category, String description) {
|
||||||
NBLabels labels = base.getLabels().and("name", metricFamilyName);
|
NBLabels labels = base.getLabels().and("name", metricFamilyName);
|
||||||
NBMetricHistogram histogram = new NBMetricHistogram(labels, new DeltaHdrHistogramReservoir(labels, hdrdigits), description, category);
|
NBMetricHistogram histogram = new NBMetricHistogram(labels, new DeltaHdrHistogramReservoir(labels, hdrdigits), description, category);
|
||||||
@ -120,7 +146,7 @@ public class NBCreators {
|
|||||||
return histogram;
|
return histogram;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public AttachedMetricsSummaryReporter summaryReporter(long millis, String... labelspecs) {
|
// public AttachedMetricsSummaryReporter summaryReporter(long millis, String... labelspecs) {
|
||||||
// logger.debug("attaching summary reporter to " + base.description());
|
// logger.debug("attaching summary reporter to " + base.description());
|
||||||
// NBLabels extraLabels = NBLabels.forKV((Object[]) labelspecs);
|
// NBLabels extraLabels = NBLabels.forKV((Object[]) labelspecs);
|
||||||
// AttachedMetricsSummaryReporter reporter = new AttachedMetricsSummaryReporter(base, extraLabels, millis);
|
// AttachedMetricsSummaryReporter reporter = new AttachedMetricsSummaryReporter(base, extraLabels, millis);
|
||||||
@ -198,7 +224,7 @@ public class NBCreators {
|
|||||||
private Logger logger = LogManager.getLogger(Log4JMetricsReporter.class);
|
private Logger logger = LogManager.getLogger(Log4JMetricsReporter.class);
|
||||||
private Log4JMetricsReporter.LoggingLevel loggingLevel = Log4JMetricsReporter.LoggingLevel.INFO;
|
private Log4JMetricsReporter.LoggingLevel loggingLevel = Log4JMetricsReporter.LoggingLevel.INFO;
|
||||||
private Marker marker;
|
private Marker marker;
|
||||||
private MetricFilter filter= new MetricInstanceFilter();
|
private MetricFilter filter = new MetricInstanceFilter();
|
||||||
private boolean oneLastTime = false;
|
private boolean oneLastTime = false;
|
||||||
private NBLabels labels;
|
private NBLabels labels;
|
||||||
private long millis = 1000;
|
private long millis = 1000;
|
||||||
@ -206,34 +232,42 @@ public class NBCreators {
|
|||||||
public Log4jReporterBuilder(NBComponent component) {
|
public Log4jReporterBuilder(NBComponent component) {
|
||||||
this.component = component;
|
this.component = component;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log4jReporterBuilder oneLastTime(final boolean oneLastTime) {
|
public Log4jReporterBuilder oneLastTime(final boolean oneLastTime) {
|
||||||
this.oneLastTime = oneLastTime;
|
this.oneLastTime = oneLastTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log4jReporterBuilder interval(final int interval) {
|
public Log4jReporterBuilder interval(final int interval) {
|
||||||
this.millis = interval;
|
this.millis = interval;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log4jReporterBuilder outputTo(final Logger logger) {
|
public Log4jReporterBuilder outputTo(final Logger logger) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log4jReporterBuilder markWith(final Marker marker) {
|
public Log4jReporterBuilder markWith(final Marker marker) {
|
||||||
this.marker = marker;
|
this.marker = marker;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log4jReporterBuilder labels(final NBLabels labels) {
|
public Log4jReporterBuilder labels(final NBLabels labels) {
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log4jReporterBuilder filter(final MetricFilter filter) {
|
public Log4jReporterBuilder filter(final MetricFilter filter) {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log4jReporterBuilder withLoggingLevel(final Log4JMetricsReporter.LoggingLevel loggingLevel) {
|
public Log4jReporterBuilder withLoggingLevel(final Log4JMetricsReporter.LoggingLevel loggingLevel) {
|
||||||
this.loggingLevel = loggingLevel;
|
this.loggingLevel = loggingLevel;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log4JMetricsReporter build() {
|
public Log4JMetricsReporter build() {
|
||||||
final LoggerProxy loggerProxy = switch (this.loggingLevel) {
|
final LoggerProxy loggerProxy = switch (this.loggingLevel) {
|
||||||
case TRACE -> new TraceLoggerProxy(this.logger);
|
case TRACE -> new TraceLoggerProxy(this.logger);
|
||||||
@ -245,6 +279,7 @@ public class NBCreators {
|
|||||||
return new Log4JMetricsReporter(this.component, loggerProxy, this.marker, this.filter, this.labels, this.millis, this.oneLastTime);
|
return new Log4JMetricsReporter(this.component, loggerProxy, this.marker, this.filter, this.labels, this.millis, this.oneLastTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* private class to allow logger configuration */
|
/* private class to allow logger configuration */
|
||||||
public abstract static class LoggerProxy {
|
public abstract static class LoggerProxy {
|
||||||
protected final Logger logger;
|
protected final Logger logger;
|
||||||
@ -356,22 +391,27 @@ public class NBCreators {
|
|||||||
this.component = component;
|
this.component = component;
|
||||||
this.output = output;
|
this.output = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConsoleReporterBuilder labels(NBLabels labels) {
|
public ConsoleReporterBuilder labels(NBLabels labels) {
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConsoleReporterBuilder interval(int interval) {
|
public ConsoleReporterBuilder interval(int interval) {
|
||||||
this.interval = interval;
|
this.interval = interval;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConsoleReporterBuilder oneLastTime(boolean oneLastTime) {
|
public ConsoleReporterBuilder oneLastTime(boolean oneLastTime) {
|
||||||
this.oneLastTime = oneLastTime;
|
this.oneLastTime = oneLastTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConsoleReporterBuilder disabledMetricAttributes(Set<MetricAttribute> disabledMetricAttributes) {
|
public ConsoleReporterBuilder disabledMetricAttributes(Set<MetricAttribute> disabledMetricAttributes) {
|
||||||
this.disabledMetricAttributes = disabledMetricAttributes;
|
this.disabledMetricAttributes = disabledMetricAttributes;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConsoleReporter build() {
|
public ConsoleReporter build() {
|
||||||
return new ConsoleReporter(component, labels, interval, oneLastTime, output, disabledMetricAttributes);
|
return new ConsoleReporter(component, labels, interval, oneLastTime, output, disabledMetricAttributes);
|
||||||
}
|
}
|
||||||
@ -387,10 +427,12 @@ public class NBCreators {
|
|||||||
this.component = component;
|
this.component = component;
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvOutputWriterBuilder headers(String... headers) {
|
public CsvOutputWriterBuilder headers(String... headers) {
|
||||||
this.headers = headers;
|
this.headers = headers;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvOutputPluginWriter build() {
|
public CsvOutputPluginWriter build() {
|
||||||
return new CsvOutputPluginWriter(component, filename, headers);
|
return new CsvOutputPluginWriter(component, filename, headers);
|
||||||
}
|
}
|
||||||
@ -406,26 +448,32 @@ public class NBCreators {
|
|||||||
public CsvReporterBuilder(NBComponent component) {
|
public CsvReporterBuilder(NBComponent component) {
|
||||||
this.component = component;
|
this.component = component;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvReporterBuilder labels(NBLabels labels) {
|
public CsvReporterBuilder labels(NBLabels labels) {
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvReporterBuilder path(Path reportTo) {
|
public CsvReporterBuilder path(Path reportTo) {
|
||||||
this.reportTo = reportTo;
|
this.reportTo = reportTo;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvReporterBuilder path(String reportTo) {
|
public CsvReporterBuilder path(String reportTo) {
|
||||||
this.reportTo = Path.of(reportTo);
|
this.reportTo = Path.of(reportTo);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvReporterBuilder interval(int interval) {
|
public CsvReporterBuilder interval(int interval) {
|
||||||
this.interval = interval;
|
this.interval = interval;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvReporterBuilder filter(MetricInstanceFilter filter) {
|
public CsvReporterBuilder filter(MetricInstanceFilter filter) {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvReporter build() {
|
public CsvReporter build() {
|
||||||
return new CsvReporter(component, reportTo, interval, filter, labels);
|
return new CsvReporter(component, reportTo, interval, filter, labels);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 nosqlbench
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.nosqlbench.nb.api.engine.metrics;
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
|
||||||
|
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricGauge;
|
||||||
|
import io.nosqlbench.nb.api.labels.NBLabels;
|
||||||
|
import io.nosqlbench.nb.api.stats.StatBucket;
|
||||||
|
|
||||||
|
import java.util.DoubleSummaryStatistics;
|
||||||
|
import java.util.function.DoubleConsumer;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a discrete stat reservoir as a gauge.
|
||||||
|
*/
|
||||||
|
public class WindowSummaryGauge implements NBMetricGauge, DoubleConsumer {
|
||||||
|
private final NBLabels labels;
|
||||||
|
private final Stat stat;
|
||||||
|
private final StatBucket stats;
|
||||||
|
private final String description;
|
||||||
|
private final MetricCategory[] categories;
|
||||||
|
private final int window;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String typeName() {
|
||||||
|
return "gauge";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MetricCategory[] getCategories() {
|
||||||
|
return this.categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Stat {
|
||||||
|
Min,
|
||||||
|
Max,
|
||||||
|
Average,
|
||||||
|
Count,
|
||||||
|
Sum
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public WindowSummaryGauge(int window, NBLabels labels, Stat stat, String description,
|
||||||
|
MetricCategory... categories) {
|
||||||
|
this.labels = labels;
|
||||||
|
this.stat = stat;
|
||||||
|
this.description = description;
|
||||||
|
this.categories = categories;
|
||||||
|
this.window = window;
|
||||||
|
this.stats = new StatBucket(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void accept(double value) {
|
||||||
|
stats.apply(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized Double getValue() {
|
||||||
|
return switch(stat) {
|
||||||
|
case Min -> stats.getMin();
|
||||||
|
case Max -> stats.getMax();
|
||||||
|
case Average -> stats.getAverage();
|
||||||
|
case Count -> (double) stats.getCount();
|
||||||
|
case Sum -> stats.getSum();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBLabels getLabels() {
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.labels.toString()+":"+this.stats.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 nosqlbench
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.nosqlbench.nb.api.engine.metrics.wrappers;
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.components.core.NBComponent;
|
||||||
|
import io.nosqlbench.nb.api.engine.metrics.WindowSummaryGauge;
|
||||||
|
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
|
||||||
|
import io.nosqlbench.nb.api.labels.NBLabeledElement;
|
||||||
|
import io.nosqlbench.nb.api.labels.NBLabels;
|
||||||
|
import io.nosqlbench.nb.api.stats.StatBucket;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class WindowedRelevancyMeasures implements NBLabeledElement {
|
||||||
|
|
||||||
|
private final NBComponent parent;
|
||||||
|
private final NBLabels labels;
|
||||||
|
private final List<RelevancyFunction> functions = new ArrayList<>();
|
||||||
|
private final List<WindowSummaryGauge> gauges = new ArrayList<>();
|
||||||
|
private final int window;
|
||||||
|
private int offset = 0;
|
||||||
|
|
||||||
|
public WindowedRelevancyMeasures(NBComponent parent, int window) {
|
||||||
|
this(parent, NBLabels.forKV(),window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindowedRelevancyMeasures(NBComponent parent, NBLabels labels, int window) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.labels = labels;
|
||||||
|
this.window = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindowedRelevancyMeasures(NBComponent parent, Map<String, String> labels, int window) {
|
||||||
|
this(parent, NBLabels.forMap(labels), window);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBLabels getLabels() {
|
||||||
|
return parent.getLabels().and(labels);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindowedRelevancyMeasures addFunction(RelevancyFunction... f) {
|
||||||
|
for (RelevancyFunction function : f) {
|
||||||
|
this.functions.add(function);
|
||||||
|
function.prependLabels(this);
|
||||||
|
WindowSummaryGauge gauge = parent.create().windowSummaryGauge(
|
||||||
|
function.getUniqueName(),
|
||||||
|
window,
|
||||||
|
List.of("Average"),
|
||||||
|
MetricCategory.Accuracy,
|
||||||
|
WindowSummaryGauge.Stat.Average.toString()
|
||||||
|
);
|
||||||
|
this.gauges.add(gauge);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void accept(int[] relevant, int[] actual) {
|
||||||
|
offset++;
|
||||||
|
if (offset >= window) {
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < functions.size(); i++) {
|
||||||
|
double metricValue = functions.get(i).apply(relevant, actual);
|
||||||
|
gauges.get(i).accept(metricValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (WindowSummaryGauge gauge : gauges) {
|
||||||
|
sb.append(gauge.toString()).append("\n");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.nosqlbench.scenarios.simframe.stabilization;
|
package io.nosqlbench.nb.api.stats;
|
||||||
|
|
||||||
public class DoubleRing {
|
public class DoubleRing {
|
||||||
private final double[] dbuf;
|
private final double[] dbuf;
|
||||||
@ -47,4 +47,21 @@ public class DoubleRing {
|
|||||||
public int count() {
|
public int count() {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double min() {
|
||||||
|
double min = Double.MAX_VALUE;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
min = Math.min(min,dbuf[i]);
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double max() {
|
||||||
|
double max = Double.MIN_VALUE;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
max = Math.max(max,dbuf[i]);
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -14,10 +14,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.nosqlbench.scenarios.simframe.stabilization;
|
package io.nosqlbench.nb.api.stats;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a relatively efficient statistics bucket which can maintain moving
|
||||||
|
* aggregates over a window of samples for count, mean, variance, stddev, sum.
|
||||||
|
* This is particularly useful when you know that each update to the data
|
||||||
|
* will likely be used in a query.
|
||||||
|
*/
|
||||||
public final class StatBucket {
|
public final class StatBucket {
|
||||||
DoubleRing ringbuf;
|
DoubleRing ringbuf;
|
||||||
private double mean;
|
private double mean;
|
||||||
@ -98,10 +104,31 @@ public final class StatBucket {
|
|||||||
return "StatBucket[" +
|
return "StatBucket[" +
|
||||||
"count=" + ringbuf.count() + ", " +
|
"count=" + ringbuf.count() + ", " +
|
||||||
"mean=" + mean + ", " +
|
"mean=" + mean + ", " +
|
||||||
"stddev=" + stddev() + ']';
|
"stddev=" + stddev() + ", " +
|
||||||
|
"variance=" + variance() + ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean primed() {
|
public boolean primed() {
|
||||||
return this.count()== ringbuf.size();
|
return this.count()== ringbuf.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getMin() {
|
||||||
|
return ringbuf.min();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMax() {
|
||||||
|
return ringbuf.max();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAverage() {
|
||||||
|
return this.mean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCount() {
|
||||||
|
return count();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSum() {
|
||||||
|
return this.mean() * this.count();
|
||||||
|
}
|
||||||
}
|
}
|
@ -56,14 +56,14 @@ public class SystemIdTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testPackedNodeId() {
|
public void testPackedNodeId() {
|
||||||
String packedNodeId = SystemId.getPackedNodeId();
|
String packedNodeId = SystemId.getPackedNodeId();
|
||||||
assertThat(packedNodeId).matches("[0-9A-Za-z_-]+");
|
assertThat(packedNodeId).matches("[0-9A-Za-z_~-]+");
|
||||||
logger.info("packed node id: " + packedNodeId);
|
logger.info("packed node id: " + packedNodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenSessionCode() {
|
public void testGenSessionCode() {
|
||||||
String sessionCode=SystemId.genSessionCode(234L);
|
String sessionCode=SystemId.genSessionCode(234L);
|
||||||
assertThat(sessionCode).matches("[0-9a-zA-Z~-]+");
|
assertThat(sessionCode).matches("[0-9a-zA-Z_~-]+");
|
||||||
logger.info("session code: " + sessionCode);
|
logger.info("session code: " + sessionCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 nosqlbench
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.nosqlbench.nb.api.stats;
|
||||||
|
|
||||||
|
import org.assertj.core.data.Offset;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class StatBucketTest {
|
||||||
|
@Test
|
||||||
|
public void testStreamingMean() {
|
||||||
|
var bucket = new StatBucket();
|
||||||
|
bucket.apply(5.0d);
|
||||||
|
assertThat(bucket.mean()).isCloseTo(5.0d, Offset.offset(0.001d));
|
||||||
|
bucket.apply(10.0d);
|
||||||
|
assertThat(bucket.mean()).isCloseTo(7.5d, Offset.offset(0.001d));
|
||||||
|
bucket.apply(15.0d);
|
||||||
|
assertThat(bucket.mean()).isCloseTo(10.0d, Offset.offset(0.001d));
|
||||||
|
bucket.apply(20.0d);
|
||||||
|
assertThat(bucket.mean()).isCloseTo(12.5d, Offset.offset(0.001d));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStreamingComputations() {
|
||||||
|
double[] samples = new double[]{2, 4, 4, 4, 5, 5, 7, 9};
|
||||||
|
|
||||||
|
var bucket = new StatBucket(8);
|
||||||
|
for (int i = 0; i < samples.length * 10; i++) {
|
||||||
|
bucket.apply(samples[i % samples.length]);
|
||||||
|
if (i > 0 && (i % samples.length) == 0) {
|
||||||
|
assertThat(bucket.mean()).isCloseTo(5, Offset.offset(0.001d));
|
||||||
|
assertThat(bucket.stddev()).isCloseTo(2.0, Offset.offset(0.001d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testErrorAccumulation1() {
|
||||||
|
var bucket = new StatBucket(11);
|
||||||
|
for (long base = 1; base <10000000000000000L ; base*=10) {
|
||||||
|
for (int i = 0; i< 10; i++) {
|
||||||
|
long value = base+i;
|
||||||
|
bucket.apply(value);
|
||||||
|
}
|
||||||
|
for (int i = 10; i < 20; i++) {
|
||||||
|
long value = base+i;
|
||||||
|
bucket.apply(value);
|
||||||
|
double streamingMean = bucket.mean();
|
||||||
|
assertThat(streamingMean).isCloseTo((double)(value-5), Offset.offset(0.03d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,6 +19,7 @@ package io.nosqlbench.engine.cli.atfiles;
|
|||||||
import io.nosqlbench.nb.api.nbio.Content;
|
import io.nosqlbench.nb.api.nbio.Content;
|
||||||
import io.nosqlbench.nb.api.nbio.NBIO;
|
import io.nosqlbench.nb.api.nbio.NBIO;
|
||||||
import io.nosqlbench.nb.api.nbio.NBPathsAPI;
|
import io.nosqlbench.nb.api.nbio.NBPathsAPI;
|
||||||
|
import io.nosqlbench.nb.api.system.NBEnvironment;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -166,8 +167,10 @@ public class NBAtFile {
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
String word = iter.next();
|
String word = iter.next();
|
||||||
String modified = word.replaceAll("\\$\\{DIR}",parent.toString());
|
String modified = word.replaceAll("\\$\\{DIR}",parent.toString());
|
||||||
|
Optional<String> interpolatedString = NBEnvironment.INSTANCE.interpolate(modified);
|
||||||
|
String value = interpolatedString.orElseThrow(() -> new RuntimeException("Unable to find environment variable or property in text '"+modified+"' in atfile '" + atPath + "'"));
|
||||||
iter.remove();
|
iter.remove();
|
||||||
iter.add(modified);
|
iter.add(value);
|
||||||
}
|
}
|
||||||
return formatted;
|
return formatted;
|
||||||
}
|
}
|
||||||
|
@ -91,4 +91,15 @@ class NBAtFileTest {
|
|||||||
assertThat(strings).containsExactly("arg1","arg1","arg1","arg2","arg3","arg3","arg3","deepval");
|
assertThat(strings).containsExactly("arg1","arg1","arg1","arg2","arg3","arg3","arg3","deepval");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAtfileEnvironmentVariable() {
|
||||||
|
LinkedList<String> strings = NBAtFile.includeAt("@src/test/resources/atfiles/environment_variable.yaml");
|
||||||
|
assertThat(strings).containsExactly("My value environment");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAtfileMissingEnvironmentVariable() {
|
||||||
|
assertThrows(RuntimeException.class, () -> NBAtFile.includeAt("@src/test/resources/atfiles/environment_variable_missing.yaml:>:"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
- My ${TEST_ENV_VAR} environment
|
@ -0,0 +1 @@
|
|||||||
|
- My ${MISSING_ENV_VAR} environment
|
@ -313,7 +313,7 @@ public class NBCLIScenarioPreprocessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final Pattern templatePattern = Pattern.compile("TEMPLATE\\((.+?)\\)");
|
private static final Pattern templatePattern = Pattern.compile("TEMPLATE\\((.+?)\\)");
|
||||||
private static final Pattern innerTemplatePattern = Pattern.compile("TEMPLATE\\((.+?)$");
|
private static final Pattern innerTemplatePattern = Pattern.compile("TEMPLATE\\((.+?)\\)");
|
||||||
private static final Pattern templatePattern2 = Pattern.compile("<<(.+?)>>");
|
private static final Pattern templatePattern2 = Pattern.compile("<<(.+?)>>");
|
||||||
|
|
||||||
public static List<WorkloadDesc> filterForScenarios(List<Content<?>> candidates) {
|
public static List<WorkloadDesc> filterForScenarios(List<Content<?>> candidates) {
|
||||||
@ -444,22 +444,18 @@ public class NBCLIScenarioPreprocessor {
|
|||||||
String match = matcher.group(1);
|
String match = matcher.group(1);
|
||||||
|
|
||||||
Matcher innerMatcher = innerTemplatePattern.matcher(match);
|
Matcher innerMatcher = innerTemplatePattern.matcher(match);
|
||||||
String[] matchArray = match.split("[,:]");
|
|
||||||
if (matchArray.length==1) {
|
|
||||||
matchArray = new String[]{matchArray[0],""};
|
|
||||||
}
|
|
||||||
// if (matchArray.length!=2) {
|
|
||||||
// throw new BasicError("TEMPLATE form must have two arguments separated by a comma, like 'TEMPLATE(a,b), not '" + match +"'");
|
|
||||||
// }
|
|
||||||
//TODO: support recursive matches
|
|
||||||
if (innerMatcher.find()) {
|
if (innerMatcher.find()) {
|
||||||
String[] innerMatch = innerMatcher.group(1).split("[,:]");
|
String innerMatch = innerMatcher.group(1);
|
||||||
|
templates = matchTemplates("TEMPLATE(" + innerMatch + ")", templates);
|
||||||
//We want the outer name with the inner default value
|
String resolvedInner = templates.getOrDefault(innerMatch.split("[,:]")[0], "");
|
||||||
templates.put(matchArray[0], innerMatch[1]);
|
match = match.replace("TEMPLATE(" + innerMatch + ")", resolvedInner);
|
||||||
} else {
|
|
||||||
templates.put(matchArray[0], matchArray[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String[] matchArray = match.split("[,:]");
|
||||||
|
if (matchArray.length == 1) {
|
||||||
|
matchArray = new String[]{matchArray[0], ""};
|
||||||
|
}
|
||||||
|
templates.put(matchArray[0], matchArray[1]);
|
||||||
}
|
}
|
||||||
matcher = templatePattern2.matcher(line);
|
matcher = templatePattern2.matcher(line);
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ printf "getting appimage tool and building image...\n";
|
|||||||
chmod +x appimagetool-x86_64.AppImage
|
chmod +x appimagetool-x86_64.AppImage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# note if your linux has errors with the following then see https://docs.appimage.org/user-guide/troubleshooting/fuse.html
|
||||||
ARCH=x86_64 ./appimagetool-x86_64.AppImage NB.AppDir ${BIN_NAME}
|
ARCH=x86_64 ./appimagetool-x86_64.AppImage NB.AppDir ${BIN_NAME}
|
||||||
# && chmod +x ${BIN_NAME}
|
# && chmod +x ${BIN_NAME}
|
||||||
)
|
)
|
||||||
|
@ -75,6 +75,7 @@ printf "getting appimage tool and building image...\n";
|
|||||||
chmod +x appimagetool-x86_64.AppImage
|
chmod +x appimagetool-x86_64.AppImage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# note if your linux has errors with the following then see https://docs.appimage.org/user-guide/troubleshooting/fuse.html
|
||||||
ARCH=x86_64 ./appimagetool-x86_64.AppImage NB.AppDir ${BIN_NAME}
|
ARCH=x86_64 ./appimagetool-x86_64.AppImage NB.AppDir ${BIN_NAME}
|
||||||
# && chmod +x ${BIN_NAME}
|
# && chmod +x ${BIN_NAME}
|
||||||
)
|
)
|
||||||
|
@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
package io.nosqlbench.scenarios.simframe.stabilization;
|
package io.nosqlbench.scenarios.simframe.stabilization;
|
||||||
|
|
||||||
|
import io.nosqlbench.nb.api.stats.StatBucket;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.OptionalDouble;
|
|
||||||
import java.util.function.DoubleSupplier;
|
import java.util.function.DoubleSupplier;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 nosqlbench
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.nosqlbench.scenarios.simframe.stats;
|
|
||||||
|
|
||||||
import io.nosqlbench.scenarios.simframe.stabilization.StatBucket;
|
|
||||||
import org.assertj.core.data.Offset;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
class StatBucketTest {
|
|
||||||
@Test
|
|
||||||
public void testStreamingMean() {
|
|
||||||
var bucket = new StatBucket();
|
|
||||||
bucket.apply(5.0d);
|
|
||||||
assertThat(bucket.mean()).isCloseTo(5.0d,Offset.offset(0.001d));
|
|
||||||
bucket.apply(10.0d);
|
|
||||||
assertThat(bucket.mean()).isCloseTo(7.5d,Offset.offset(0.001d));
|
|
||||||
bucket.apply(15.0d);
|
|
||||||
assertThat(bucket.mean()).isCloseTo(10.0d,Offset.offset(0.001d));
|
|
||||||
bucket.apply(20.0d);
|
|
||||||
assertThat(bucket.mean()).isCloseTo(12.5d,Offset.offset(0.001d));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStreamingComputations() {
|
|
||||||
double[] samples = new double[]{2,4,4,4,5,5,7,9};
|
|
||||||
|
|
||||||
var bucket = new StatBucket(8);
|
|
||||||
for (int i = 0; i < samples.length * 10; i++) {
|
|
||||||
bucket.apply(samples[i%samples.length]);
|
|
||||||
if (i>0&&(i%samples.length)==0) {
|
|
||||||
assertThat(bucket.mean()).isCloseTo(5,Offset.offset(0.001d));
|
|
||||||
assertThat(bucket.stddev()).isCloseTo(2.0,Offset.offset(0.001d));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user