Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
hpdos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
SYNERG
hpdos
Commits
f7053183
Commit
f7053183
authored
May 14, 2021
by
NILANJAN DAW
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added DPDK and java impl: lsmtree based metadata service
parent
7b6d2857
Changes
84
Hide whitespace changes
Inline
Side-by-side
Showing
84 changed files
with
9553 additions
and
0 deletions
+9553
-0
code/lsm-tree-impl/host-app/hpdos_client/.gitattributes
code/lsm-tree-impl/host-app/hpdos_client/.gitattributes
+6
-0
code/lsm-tree-impl/host-app/hpdos_client/.gitignore
code/lsm-tree-impl/host-app/hpdos_client/.gitignore
+5
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/.gitignore
code/lsm-tree-impl/host-app/hpdos_client/.idea/.gitignore
+3
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/.name
code/lsm-tree-impl/host-app/hpdos_client/.idea/.name
+1
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/compiler.xml
code/lsm-tree-impl/host-app/hpdos_client/.idea/compiler.xml
+6
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/gradle.xml
code/lsm-tree-impl/host-app/hpdos_client/.idea/gradle.xml
+22
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/jarRepositories.xml
...tree-impl/host-app/hpdos_client/.idea/jarRepositories.xml
+25
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/misc.xml
code/lsm-tree-impl/host-app/hpdos_client/.idea/misc.xml
+7
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/modules.xml
code/lsm-tree-impl/host-app/hpdos_client/.idea/modules.xml
+8
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/uiDesigner.xml
.../lsm-tree-impl/host-app/hpdos_client/.idea/uiDesigner.xml
+124
-0
code/lsm-tree-impl/host-app/hpdos_client/.idea/vcs.xml
code/lsm-tree-impl/host-app/hpdos_client/.idea/vcs.xml
+6
-0
code/lsm-tree-impl/host-app/hpdos_client/app.config
code/lsm-tree-impl/host-app/hpdos_client/app.config
+8
-0
code/lsm-tree-impl/host-app/hpdos_client/app/build.gradle
code/lsm-tree-impl/host-app/hpdos_client/app/build.gradle
+67
-0
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/ClientRunner.java
...os_client/app/src/main/java/HpdosClient/ClientRunner.java
+250
-0
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/ConfigConstants.java
...client/app/src/main/java/HpdosClient/ConfigConstants.java
+7
-0
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/MessageFormat/MessageConstants.java
...main/java/HpdosClient/MessageFormat/MessageConstants.java
+26
-0
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/MessageFormat/RequestBuilder.java
...c/main/java/HpdosClient/MessageFormat/RequestBuilder.java
+32
-0
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/MessageFormat/ResponseBuilder.java
.../main/java/HpdosClient/MessageFormat/ResponseBuilder.java
+55
-0
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/proto/PacketFormat.proto
...st-app/hpdos_client/app/src/main/proto/PacketFormat.proto
+72
-0
code/lsm-tree-impl/host-app/hpdos_client/app/src/test/java/HpdosClient/AppTest.java
...p/hpdos_client/app/src/test/java/HpdosClient/AppTest.java
+14
-0
code/lsm-tree-impl/host-app/hpdos_client/gradle/wrapper/gradle-wrapper.properties
...app/hpdos_client/gradle/wrapper/gradle-wrapper.properties
+5
-0
code/lsm-tree-impl/host-app/hpdos_client/gradlew
code/lsm-tree-impl/host-app/hpdos_client/gradlew
+185
-0
code/lsm-tree-impl/host-app/hpdos_client/gradlew.bat
code/lsm-tree-impl/host-app/hpdos_client/gradlew.bat
+89
-0
code/lsm-tree-impl/host-app/hpdos_client/settings.gradle
code/lsm-tree-impl/host-app/hpdos_client/settings.gradle
+11
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/.gitignore
code/lsm-tree-impl/host-app/hpdos_server/.idea/.gitignore
+3
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/.name
code/lsm-tree-impl/host-app/hpdos_server/.idea/.name
+1
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/compiler.xml
code/lsm-tree-impl/host-app/hpdos_server/.idea/compiler.xml
+6
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/gradle.xml
code/lsm-tree-impl/host-app/hpdos_server/.idea/gradle.xml
+21
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/jarRepositories.xml
...tree-impl/host-app/hpdos_server/.idea/jarRepositories.xml
+25
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/misc.xml
code/lsm-tree-impl/host-app/hpdos_server/.idea/misc.xml
+5
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/modules.xml
code/lsm-tree-impl/host-app/hpdos_server/.idea/modules.xml
+8
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/uiDesigner.xml
.../lsm-tree-impl/host-app/hpdos_server/.idea/uiDesigner.xml
+124
-0
code/lsm-tree-impl/host-app/hpdos_server/.idea/vcs.xml
code/lsm-tree-impl/host-app/hpdos_server/.idea/vcs.xml
+6
-0
code/lsm-tree-impl/host-app/hpdos_server/app/.classpath
code/lsm-tree-impl/host-app/hpdos_server/app/.classpath
+38
-0
code/lsm-tree-impl/host-app/hpdos_server/app/.project
code/lsm-tree-impl/host-app/hpdos_server/app/.project
+34
-0
code/lsm-tree-impl/host-app/hpdos_server/app/.settings/org.eclipse.buildship.core.prefs
...dos_server/app/.settings/org.eclipse.buildship.core.prefs
+2
-0
code/lsm-tree-impl/host-app/hpdos_server/app/build.gradle
code/lsm-tree-impl/host-app/hpdos_server/app/build.gradle
+71
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/ConfigConstants.java
...hpdos_server/app/src/main/java/hpdos/ConfigConstants.java
+16
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/MetadataServer.java
.../hpdos_server/app/src/main/java/hpdos/MetadataServer.java
+195
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/handler/HeartbeatHandler.java
...ver/app/src/main/java/hpdos/handler/HeartbeatHandler.java
+38
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/handler/IOHandler.java
...dos_server/app/src/main/java/hpdos/handler/IOHandler.java
+151
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/handler/NetworkHandler.java
...erver/app/src/main/java/hpdos/handler/NetworkHandler.java
+117
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/handler/ReplicateHandler.java
...ver/app/src/main/java/hpdos/handler/ReplicateHandler.java
+40
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/InlineReplicationService.java
...app/src/main/java/hpdos/lib/InlineReplicationService.java
+114
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/MasterFollower.java
...os_server/app/src/main/java/hpdos/lib/MasterFollower.java
+55
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/MemoryStorageService.java
...ver/app/src/main/java/hpdos/lib/MemoryStorageService.java
+65
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/ReplicationService.java
...erver/app/src/main/java/hpdos/lib/ReplicationService.java
+14
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/RocksDBStorageService.java
...er/app/src/main/java/hpdos/lib/RocksDBStorageService.java
+200
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/StorageModel.java
...pdos_server/app/src/main/java/hpdos/lib/StorageModel.java
+94
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/StorageService.java
...os_server/app/src/main/java/hpdos/lib/StorageService.java
+8
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/StoredModel.java
...hpdos_server/app/src/main/java/hpdos/lib/StoredModel.java
+27
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/message/MessageConstants.java
...ver/app/src/main/java/hpdos/message/MessageConstants.java
+32
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/message/RequestBuilder.java
...erver/app/src/main/java/hpdos/message/RequestBuilder.java
+37
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/message/ResponseBuilder.java
...rver/app/src/main/java/hpdos/message/ResponseBuilder.java
+69
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/proto/Heartbeat.proto
.../host-app/hpdos_server/app/src/main/proto/Heartbeat.proto
+29
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/proto/PacketFormat.proto
...st-app/hpdos_server/app/src/main/proto/PacketFormat.proto
+72
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/proto/Replicate.proto
.../host-app/hpdos_server/app/src/main/proto/Replicate.proto
+25
-0
code/lsm-tree-impl/host-app/hpdos_server/app/src/test/java/hpdos/AppTest.java
...ost-app/hpdos_server/app/src/test/java/hpdos/AppTest.java
+14
-0
code/lsm-tree-impl/host-app/hpdos_server/gradle/wrapper/gradle-wrapper.properties
...app/hpdos_server/gradle/wrapper/gradle-wrapper.properties
+5
-0
code/lsm-tree-impl/host-app/hpdos_server/gradlew
code/lsm-tree-impl/host-app/hpdos_server/gradlew
+185
-0
code/lsm-tree-impl/host-app/hpdos_server/gradlew.bat
code/lsm-tree-impl/host-app/hpdos_server/gradlew.bat
+89
-0
code/lsm-tree-impl/host-app/hpdos_server/settings.gradle
code/lsm-tree-impl/host-app/hpdos_server/settings.gradle
+11
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/Makefile
...etadata-server-read-offload/dpdk-server/kv-cache/Makefile
+43
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/kv_str_main.c
...ta-server-read-offload/dpdk-server/kv-cache/kv_str_main.c
+1162
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/kv_wo_coll_main.c
...erver-read-offload/dpdk-server/kv-cache/kv_wo_coll_main.c
+1172
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/main.c
.../metadata-server-read-offload/dpdk-server/kv-cache/main.c
+1400
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/meson.build
...data-server-read-offload/dpdk-server/kv-cache/meson.build
+13
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/l2fwd/Makefile
...p/metadata-server-read-offload/dpdk-server/l2fwd/Makefile
+43
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/l2fwd/main.c
...app/metadata-server-read-offload/dpdk-server/l2fwd/main.c
+938
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/l2fwd/meson.build
...etadata-server-read-offload/dpdk-server/l2fwd/meson.build
+13
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/client
...app/metadata-server-read-offload/load-gen/load_gen/client
+0
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/client.cpp
...metadata-server-read-offload/load-gen/load_gen/client.cpp
+541
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/client.h
...p/metadata-server-read-offload/load-gen/load_gen/client.h
+11
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/inst.csv
...p/metadata-server-read-offload/load-gen/load_gen/inst.csv
+104
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/makefile
...p/metadata-server-read-offload/load-gen/load_gen/makefile
+9
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/network.cpp
...etadata-server-read-offload/load-gen/load_gen/network.cpp
+414
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/network.h
.../metadata-server-read-offload/load-gen/load_gen/network.h
+53
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/route.sh
...p/metadata-server-read-offload/load-gen/load_gen/route.sh
+9
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/stats.csv
.../metadata-server-read-offload/load-gen/load_gen/stats.csv
+96
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/ue.cpp
...app/metadata-server-read-offload/load-gen/load_gen/ue.cpp
+187
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/ue.h
...c-app/metadata-server-read-offload/load-gen/load_gen/ue.h
+18
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/utils.cpp
.../metadata-server-read-offload/load-gen/load_gen/utils.cpp
+112
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/utils.h
...pp/metadata-server-read-offload/load-gen/load_gen/utils.h
+109
-0
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/udp-time.py
...nic-app/metadata-server-read-offload/load-gen/udp-time.py
+26
-0
No files found.
code/lsm-tree-impl/host-app/hpdos_client/.gitattributes
0 → 100644
View file @
f7053183
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf
code/lsm-tree-impl/host-app/hpdos_client/.gitignore
0 → 100644
View file @
f7053183
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build
code/lsm-tree-impl/host-app/hpdos_client/.idea/.gitignore
0 → 100644
View file @
f7053183
# Default ignored files
/shelf/
/workspace.xml
code/lsm-tree-impl/host-app/hpdos_client/.idea/.name
0 → 100644
View file @
f7053183
HpdosClient
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/.idea/compiler.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"CompilerConfiguration"
>
<bytecodeTargetLevel
target=
"14"
/>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/.idea/gradle.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"GradleMigrationSettings"
migrationVersion=
"1"
/>
<component
name=
"GradleSettings"
>
<option
name=
"linkedExternalProjectsSettings"
>
<GradleProjectSettings>
<option
name=
"delegatedBuild"
value=
"true"
/>
<option
name=
"testRunner"
value=
"GRADLE"
/>
<option
name=
"distributionType"
value=
"LOCAL"
/>
<option
name=
"externalProjectPath"
value=
"$PROJECT_DIR$"
/>
<option
name=
"gradleHome"
value=
"/usr/local/Cellar/gradle/6.8.3/libexec"
/>
<option
name=
"gradleJvm"
value=
"14"
/>
<option
name=
"modules"
>
<set>
<option
value=
"$PROJECT_DIR$"
/>
<option
value=
"$PROJECT_DIR$/app"
/>
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/.idea/jarRepositories.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"RemoteRepositoriesConfiguration"
>
<remote-repository>
<option
name=
"id"
value=
"central"
/>
<option
name=
"name"
value=
"Maven Central repository"
/>
<option
name=
"url"
value=
"https://repo1.maven.org/maven2"
/>
</remote-repository>
<remote-repository>
<option
name=
"id"
value=
"jboss.community"
/>
<option
name=
"name"
value=
"JBoss Community repository"
/>
<option
name=
"url"
value=
"https://repository.jboss.org/nexus/content/repositories/public/"
/>
</remote-repository>
<remote-repository>
<option
name=
"id"
value=
"MavenRepo"
/>
<option
name=
"name"
value=
"MavenRepo"
/>
<option
name=
"url"
value=
"https://repo.maven.apache.org/maven2/"
/>
</remote-repository>
<remote-repository>
<option
name=
"id"
value=
"BintrayJCenter"
/>
<option
name=
"name"
value=
"BintrayJCenter"
/>
<option
name=
"url"
value=
"https://jcenter.bintray.com/"
/>
</remote-repository>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/.idea/misc.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"ExternalStorageConfigurationManager"
enabled=
"true"
/>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_14"
default=
"true"
project-jdk-name=
"14"
project-jdk-type=
"JavaSDK"
>
<output
url=
"file://$PROJECT_DIR$/out"
/>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/.idea/modules.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"ProjectModuleManager"
>
<modules>
<module
fileurl=
"file://$PROJECT_DIR$/.idea/hpdos_client.iml"
filepath=
"$PROJECT_DIR$/.idea/hpdos_client.iml"
/>
</modules>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/.idea/uiDesigner.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"Palette2"
>
<group
name=
"Swing"
>
<item
class=
"com.intellij.uiDesigner.HSpacer"
tooltip-text=
"Horizontal Spacer"
icon=
"/com/intellij/uiDesigner/icons/hspacer.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"1"
hsize-policy=
"6"
anchor=
"0"
fill=
"1"
/>
</item>
<item
class=
"com.intellij.uiDesigner.VSpacer"
tooltip-text=
"Vertical Spacer"
icon=
"/com/intellij/uiDesigner/icons/vspacer.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"1"
anchor=
"0"
fill=
"2"
/>
</item>
<item
class=
"javax.swing.JPanel"
icon=
"/com/intellij/uiDesigner/icons/panel.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"3"
hsize-policy=
"3"
anchor=
"0"
fill=
"3"
/>
</item>
<item
class=
"javax.swing.JScrollPane"
icon=
"/com/intellij/uiDesigner/icons/scrollPane.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"7"
hsize-policy=
"7"
anchor=
"0"
fill=
"3"
/>
</item>
<item
class=
"javax.swing.JButton"
icon=
"/com/intellij/uiDesigner/icons/button.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"3"
anchor=
"0"
fill=
"1"
/>
<initial-values>
<property
name=
"text"
value=
"Button"
/>
</initial-values>
</item>
<item
class=
"javax.swing.JRadioButton"
icon=
"/com/intellij/uiDesigner/icons/radioButton.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"3"
anchor=
"8"
fill=
"0"
/>
<initial-values>
<property
name=
"text"
value=
"RadioButton"
/>
</initial-values>
</item>
<item
class=
"javax.swing.JCheckBox"
icon=
"/com/intellij/uiDesigner/icons/checkBox.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"3"
anchor=
"8"
fill=
"0"
/>
<initial-values>
<property
name=
"text"
value=
"CheckBox"
/>
</initial-values>
</item>
<item
class=
"javax.swing.JLabel"
icon=
"/com/intellij/uiDesigner/icons/label.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"0"
anchor=
"8"
fill=
"0"
/>
<initial-values>
<property
name=
"text"
value=
"Label"
/>
</initial-values>
</item>
<item
class=
"javax.swing.JTextField"
icon=
"/com/intellij/uiDesigner/icons/textField.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
>
<preferred-size
width=
"150"
height=
"-1"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JPasswordField"
icon=
"/com/intellij/uiDesigner/icons/passwordField.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
>
<preferred-size
width=
"150"
height=
"-1"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JFormattedTextField"
icon=
"/com/intellij/uiDesigner/icons/formattedTextField.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
>
<preferred-size
width=
"150"
height=
"-1"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JTextArea"
icon=
"/com/intellij/uiDesigner/icons/textArea.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JTextPane"
icon=
"/com/intellij/uiDesigner/icons/textPane.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JEditorPane"
icon=
"/com/intellij/uiDesigner/icons/editorPane.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JComboBox"
icon=
"/com/intellij/uiDesigner/icons/comboBox.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"2"
anchor=
"8"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JTable"
icon=
"/com/intellij/uiDesigner/icons/table.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JList"
icon=
"/com/intellij/uiDesigner/icons/list.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"2"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JTree"
icon=
"/com/intellij/uiDesigner/icons/tree.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JTabbedPane"
icon=
"/com/intellij/uiDesigner/icons/tabbedPane.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"3"
hsize-policy=
"3"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"200"
height=
"200"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JSplitPane"
icon=
"/com/intellij/uiDesigner/icons/splitPane.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"3"
hsize-policy=
"3"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"200"
height=
"200"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JSpinner"
icon=
"/com/intellij/uiDesigner/icons/spinner.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JSlider"
icon=
"/com/intellij/uiDesigner/icons/slider.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JSeparator"
icon=
"/com/intellij/uiDesigner/icons/separator.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
/>
</item>
<item
class=
"javax.swing.JProgressBar"
icon=
"/com/intellij/uiDesigner/icons/progressbar.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"0"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JToolBar"
icon=
"/com/intellij/uiDesigner/icons/toolbar.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"0"
fill=
"1"
>
<preferred-size
width=
"-1"
height=
"20"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JToolBar$Separator"
icon=
"/com/intellij/uiDesigner/icons/toolbarSeparator.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"0"
anchor=
"0"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JScrollBar"
icon=
"/com/intellij/uiDesigner/icons/scrollbar.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"0"
anchor=
"0"
fill=
"2"
/>
</item>
</group>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/.idea/vcs.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"VcsDirectoryMappings"
>
<mapping
directory=
"$PROJECT_DIR$/../.."
vcs=
"Git"
/>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/app.config
0 → 100644
View file @
f7053183
app
.
name
=
"HPDOS-Client"
app
.
version
=
"0.1.4"
app
.
thread_count
=
12
app
.
runtime
=
5
app
.
cycle_create
=
1
app
.
cycle_read
=
4
app
.
cycle_update
=
3
app
.
cycle_delete
=
0
code/lsm-tree-impl/host-app/hpdos_client/app/build.gradle
0 → 100644
View file @
f7053183
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.8.3/userguide/building_java_projects.html
*/
plugins
{
// Apply the application plugin to add support for building a CLI application in Java.
id
'application'
id
"com.google.protobuf"
version
"0.8.15"
id
"java"
}
repositories
{
// Use JCenter for resolving dependencies.
jcenter
()
mavenCentral
()
}
dependencies
{
// Use JUnit test framework.
testImplementation
'junit:junit:4.13'
// This dependency is used by the application.
implementation
'com.google.guava:guava:29.0-jre'
implementation
group:
'com.google.protobuf'
,
name:
'protobuf-java'
,
version:
'3.15.6'
implementation
'io.grpc:grpc-netty-shaded:1.36.0'
implementation
'io.grpc:grpc-protobuf:1.36.0'
implementation
'io.grpc:grpc-stub:1.36.0'
compileOnly
'org.apache.tomcat:annotations-api:6.0.53'
// necessary for Java 9+
}
application
{
// Define the main class for the application.
mainClass
=
'HpdosClient.ClientRunner'
}
sourceSets
{
src
{
main
{
java
{
srcDirs
'build/generated/source/proto/main/grpc'
srcDirs
'build/generated/source/proto/main/java'
}
}
}
}
protobuf
{
protoc
{
artifact
=
'com.google.protobuf:protoc:3.15.6'
}
plugins
{
grpc
{
artifact
=
"io.grpc:protoc-gen-grpc-java:1.36.0"
}
}
generateProtoTasks
{
all
()*.
plugins
{
grpc
{}
}
}
}
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/ClientRunner.java
0 → 100644
View file @
f7053183
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package
HpdosClient
;
import
HpdosClient.MessageFormat.MessageConstants
;
import
HpdosClient.MessageFormat.RequestBuilder
;
import
com.google.common.base.Stopwatch
;
import
hpdos.grpc.*
;
import
io.grpc.ManagedChannel
;
import
io.grpc.ManagedChannelBuilder
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.*
;
import
java.util.concurrent.*
;
public
class
ClientRunner
{
public
static
int
parallelCount
=
10
;
public
static
int
runtime
=
0
;
private
final
String
clientID
;
public
static
String
propertiesFile
;
private
int
cCreate
,
cRead
,
cUpdate
,
cDelete
;
public
boolean
experimentEnded
=
false
;
private
List
<
Follower
>
replicaSet
;
private
Queue
<
Long
>
createTime
,
updateTime
,
readTime
,
deleteTime
;
public
ClientRunner
()
{
clientID
=
UUID
.
randomUUID
().
toString
();
Properties
properties
=
new
Properties
();
try
{
InputStream
inputStream
=
new
FileInputStream
(
propertiesFile
);
properties
.
load
(
inputStream
);
parallelCount
=
Integer
.
parseInt
((
String
)
properties
.
get
(
"app.thread_count"
));
runtime
=
Integer
.
parseInt
((
String
)
properties
.
get
(
"app.runtime"
));
cCreate
=
Integer
.
parseInt
((
String
)
properties
.
get
(
"app.cycle_create"
));
cRead
=
Integer
.
parseInt
((
String
)
properties
.
get
(
"app.cycle_read"
));
cUpdate
=
Integer
.
parseInt
((
String
)
properties
.
get
(
"app.cycle_update"
));
cDelete
=
Integer
.
parseInt
((
String
)
properties
.
get
(
"app.cycle_delete"
));
createTime
=
new
ConcurrentLinkedQueue
<>();
updateTime
=
new
ConcurrentLinkedQueue
<>();
readTime
=
new
ConcurrentLinkedQueue
<>();
deleteTime
=
new
ConcurrentLinkedQueue
<>();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
String
getGreeting
()
{
return
"Hello World!"
;
}
// create a metadata block
public
long
create
(
NetworkServiceGrpc
.
NetworkServiceBlockingStub
stub
,
String
key
,
String
value
)
{
ArrayList
<
Request
>
request
=
new
ArrayList
<>();
request
.
add
(
RequestBuilder
.
buildRequest
(
MessageConstants
.
METADATA_CREATE
,
0
,
value
.
length
(),
key
,
0
,
MessageConstants
.
METADATA_ACCESS_PRIVATE
,
this
.
clientID
,
value
));
Packet
packet
=
RequestBuilder
.
buildPacket
(
request
);
long
timestampCreateStart
=
System
.
currentTimeMillis
();
Packet
response
=
stub
.
createMetadata
(
packet
);
return
timestampCreateStart
;
}
// read back the metadata
public
Map
.
Entry
<
Packet
,
Long
>
read
(
ArrayList
<
ManagedChannel
>
channels
,
String
key
)
{
int
rnd
=
new
Random
().
nextInt
(
channels
.
size
());
NetworkServiceGrpc
.
NetworkServiceBlockingStub
stub
=
NetworkServiceGrpc
.
newBlockingStub
(
channels
.
get
(
rnd
));
ArrayList
<
Request
>
request
=
new
ArrayList
<>();
request
.
add
(
RequestBuilder
.
buildRequest
(
MessageConstants
.
METADATA_READ
,
0
,
0
,
key
,
0
,
MessageConstants
.
METADATA_ACCESS_PRIVATE
,
this
.
clientID
,
""
));
Packet
packet
=
RequestBuilder
.
buildPacket
(
request
);
long
timestampReadStart
=
System
.
currentTimeMillis
();
Packet
response
=
stub
.
readMetadata
(
packet
);
// System.out.println(response);
return
new
AbstractMap
.
SimpleEntry
<>(
response
,
timestampReadStart
);
}
public
long
update
(
NetworkServiceGrpc
.
NetworkServiceBlockingStub
stub
,
String
key
,
String
value
,
int
version
)
{
ArrayList
<
Request
>
request
=
new
ArrayList
<>();
request
.
add
(
RequestBuilder
.
buildRequest
(
MessageConstants
.
METADATA_UPDATE
,
version
,
value
.
length
(),
key
,
0
,
MessageConstants
.
METADATA_ACCESS_PRIVATE
,
this
.
clientID
,
value
));
Packet
packet
=
RequestBuilder
.
buildPacket
(
request
);
long
timestampCreateStart
=
System
.
currentTimeMillis
();
Packet
response
=
stub
.
updateMetadata
(
packet
);
return
timestampCreateStart
;
}
public
long
delete
(
NetworkServiceGrpc
.
NetworkServiceBlockingStub
stub
,
String
key
,
int
version
)
{
ArrayList
<
Request
>
request
=
new
ArrayList
<>();
request
.
add
(
RequestBuilder
.
buildRequest
(
MessageConstants
.
METADATA_DELETE
,
version
,
0
,
key
,
0
,
MessageConstants
.
METADATA_ACCESS_PRIVATE
,
this
.
clientID
,
""
));
Packet
packet
=
RequestBuilder
.
buildPacket
(
request
);
long
timestampCreateStart
=
System
.
currentTimeMillis
();
Packet
response
=
stub
.
deleteMetadata
(
packet
);
return
timestampCreateStart
;
}
public
double
runExperiment
(
String
id
,
long
experimentStartTime
)
{
final
ManagedChannel
masterChannel
=
ManagedChannelBuilder
.
forAddress
(
ConfigConstants
.
HOST
,
ConfigConstants
.
PORT
)
.
usePlaintext
()
.
build
();
ArrayList
<
ManagedChannel
>
channels
=
new
ArrayList
<>();
channels
.
add
(
masterChannel
);
for
(
Follower
follower:
replicaSet
)
{
ManagedChannel
channel
=
ManagedChannelBuilder
.
forAddress
(
follower
.
getIp
(),
follower
.
getPort
())
.
usePlaintext
()
.
build
();
channels
.
add
(
channel
);
}
for
(;;)
{
String
key
=
id
+
(
int
)
(
Math
.
random
()
*
Integer
.
MAX_VALUE
),
value
=
"dummy"
,
updatedValue
=
"dummyUpdated"
;
NetworkServiceGrpc
.
NetworkServiceBlockingStub
stub
=
NetworkServiceGrpc
.
newBlockingStub
(
masterChannel
);
for
(
int
j
=
0
;
j
<
cCreate
;
j
++)
{
long
timestampCreateStart
=
create
(
stub
,
key
,
value
);
createTime
.
add
(
System
.
currentTimeMillis
()
-
timestampCreateStart
);
}
for
(
int
j
=
0
;
j
<
cRead
;
j
++)
{
AbstractMap
.
Entry
<
Packet
,
Long
>
data
=
read
(
channels
,
key
);
readTime
.
add
(
System
.
currentTimeMillis
()
-
data
.
getValue
());
}
for
(
int
j
=
0
;
j
<
cUpdate
;
j
++)
{
AbstractMap
.
Entry
<
Packet
,
Long
>
data
=
read
(
channels
,
key
);
long
timestampUpdateStart
=
update
(
stub
,
key
,
updatedValue
,
data
.
getKey
().
getResponse
(
0
).
getAck
().
getVersion
());
readTime
.
add
(
System
.
currentTimeMillis
()
-
data
.
getValue
());
updateTime
.
add
(
System
.
currentTimeMillis
()
-
timestampUpdateStart
);
}
for
(
int
j
=
0
;
j
<
cDelete
;
j
++)
{
AbstractMap
.
Entry
<
Packet
,
Long
>
data
=
read
(
channels
,
key
);
long
timestampDeleteStart
=
delete
(
stub
,
key
,
data
.
getKey
().
getResponse
(
0
).
getAck
().
getVersion
());
readTime
.
add
(
System
.
currentTimeMillis
()
-
data
.
getValue
());
deleteTime
.
add
(
System
.
currentTimeMillis
()
-
timestampDeleteStart
);
}
long
currentTime
=
System
.
currentTimeMillis
();
if
((
currentTime
-
experimentStartTime
)
>=
runtime
*
1000L
)
break
;
}
// System.out.println(id + "runtime " + (System.currentTimeMillis() - startTime) +
// "ms qps " + qps);
masterChannel
.
shutdown
();
return
0
;
}
public
void
retrieveFollowerList
()
{
final
ManagedChannel
channel
=
ManagedChannelBuilder
.
forAddress
(
ConfigConstants
.
HOST
,
ConfigConstants
.
PORT
)
.
usePlaintext
()
.
build
();
NetworkServiceGrpc
.
NetworkServiceBlockingStub
stub
=
NetworkServiceGrpc
.
newBlockingStub
(
channel
);
ResponseList
responseList
=
stub
.
getReadReplicaList
(
null
);
this
.
replicaSet
=
responseList
.
getFollowerList
();
for
(
Follower
follower:
this
.
replicaSet
)
{
System
.
out
.
println
(
follower
);
}
channel
.
shutdown
();
}
private
void
timerService
()
{
Stopwatch
stopwatch
=
Stopwatch
.
createUnstarted
();
stopwatch
.
start
();
Timer
timer
=
new
Timer
();
timer
.
scheduleAtFixedRate
(
new
TimerTask
()
{
@Override
public
void
run
()
{
if
(
experimentEnded
)
{
timer
.
cancel
();
timer
.
purge
();
}
System
.
out
.
println
(
"Experiment ran: "
+
stopwatch
);
}
},
5000
,
5000
);
}
private
void
printStatistics
(
double
totalRuntime
)
{
long
readQps
=
0
,
createQps
=
0
,
updateQps
=
0
,
deleteQps
=
0
;
double
avgRead
=
0
,
avgCreate
=
0
,
avgUpdate
=
0
,
avgDelete
=
0
;
for
(
Long
time:
this
.
readTime
)
{
readQps
++;
avgRead
+=
time
;
}
avgRead
/=
readQps
*
1.0
;
for
(
Long
time:
this
.
createTime
)
{
createQps
++;
avgCreate
+=
time
;
}
avgCreate
/=
createQps
*
1.0
;
for
(
Long
time:
this
.
updateTime
)
{
updateQps
++;
avgUpdate
+=
time
;
}
avgUpdate
/=
updateQps
*
1.0
;
for
(
Long
time:
this
.
deleteTime
)
{
deleteQps
++;
avgDelete
+=
time
;
}
avgDelete
/=
deleteQps
*
1.0
;
double
totalQps
=
readQps
+
createQps
+
updateQps
+
deleteQps
;
System
.
out
.
println
(
"Total runtime: "
+
totalRuntime
);
System
.
out
.
println
(
"Read: "
+
readQps
+
" Create: "
+
createQps
+
" Update: "
+
updateQps
+
" Delete: "
+
deleteQps
+
" Total: "
+
totalQps
);
totalRuntime
/=
1000
;
//System.out.println("Total QPS: " + totalQps / totalRuntime + " avg query time: " + (totalQps * parallelCount / (totalRuntime)));
System
.
out
.
println
(
"Total QPS: "
+
totalQps
/
totalRuntime
+
" avg query time: "
+
((
avgRead
+
avgCreate
+
avgUpdate
+
avgDelete
)
/
4
));
System
.
out
.
println
(
"Read QPS: "
+
readQps
/
totalRuntime
+
" avg query time: "
+
avgRead
);
System
.
out
.
println
(
"Create QPS: "
+
createQps
/
totalRuntime
+
" avg query time: "
+
avgCreate
);
System
.
out
.
println
(
"Update QPS: "
+
updateQps
/
totalRuntime
+
" avg query time: "
+
avgUpdate
);
System
.
out
.
println
(
"Delete QPS: "
+
deleteQps
/
totalRuntime
+
" avg query time: "
+
avgDelete
);
}
public
static
void
main
(
String
[]
args
)
throws
InterruptedException
,
ExecutionException
{
propertiesFile
=
args
[
0
];
ClientRunner
clientRunner
=
new
ClientRunner
();
System
.
out
.
println
(
clientRunner
.
getGreeting
());
System
.
out
.
println
(
"Thread count: "
+
parallelCount
+
" runtime: "
+
runtime
+
"s"
);
ExecutorService
executorService
=
Executors
.
newFixedThreadPool
(
parallelCount
);
Thread
.
sleep
(
1000
);
// let things settle down a bit
clientRunner
.
retrieveFollowerList
();
Set
<
Callable
<
Double
>>
callables
=
new
HashSet
<>();
final
long
startTime
=
System
.
currentTimeMillis
();
for
(
int
i
=
0
;
i
<
parallelCount
;
i
++)
{
int
finalI
=
i
;
callables
.
add
(()
->
clientRunner
.
runExperiment
(
Integer
.
toString
(
finalI
),
startTime
));
}
clientRunner
.
timerService
();
List
<
Future
<
Double
>>
futures
=
executorService
.
invokeAll
(
callables
);
for
(
Future
<
Double
>
future:
futures
)
{
future
.
get
();
}
clientRunner
.
experimentEnded
=
true
;
long
endTime
=
System
.
currentTimeMillis
();
double
totalRuntime
=
endTime
-
startTime
;
clientRunner
.
printStatistics
(
totalRuntime
);
executorService
.
shutdown
();
executorService
.
awaitTermination
(
2
,
TimeUnit
.
SECONDS
);
}
}
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/ConfigConstants.java
0 → 100644
View file @
f7053183
package
HpdosClient
;
public
class
ConfigConstants
{
public
static
final
String
HOST
=
"localhost"
;
public
static
final
int
PORT
=
8080
;
public
static
final
String
URL
=
HOST
+
":"
+
PORT
;
}
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/MessageFormat/MessageConstants.java
0 → 100644
View file @
f7053183
package
HpdosClient.MessageFormat
;
public
class
MessageConstants
{
public
static
final
int
INIT_VERSION
=
0
;
public
static
final
int
INVALID_VERSION
=
-
1
;
public
static
final
int
METADATA_ACCESS_PRIVATE
=
700
;
public
static
final
int
METADATA_ACCESS_SHARED
=
777
;
// 00 to 99 - Client Server Interaction operations
public
static
final
int
PACKET_METADATA_REQUEST
=
0
;
public
static
final
int
PACKET_METADATA_RESPONSE
=
1
;
// Distinguishing ACK and NACK packets
public
static
final
int
STATUS_OK
=
200
;
public
static
final
int
STATUS_OWNER_MISMATCH
=
401
;
public
static
final
int
STATUS_REPLICATE_FAILED
=
402
;
public
static
final
int
STATUS_SERVER_NOT_MASTER
=
403
;
public
static
final
int
STATUS_KEY_NOT_FOUND
=
404
;
// 100 to 199 - HPDOS System internal operations
public
static
final
int
MASTER_HEARTBEAT
=
100
;
public
static
final
int
METADATA_CREATE
=
101
;
public
static
final
int
METADATA_READ
=
102
;
public
static
final
int
METADATA_UPDATE
=
103
;
public
static
final
int
METADATA_DELETE
=
104
;
}
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/MessageFormat/RequestBuilder.java
0 → 100644
View file @
f7053183
package
HpdosClient.MessageFormat
;
import
hpdos.grpc.Packet
;
import
hpdos.grpc.Request
;
import
java.util.ArrayList
;
public
class
RequestBuilder
{
public
static
Request
buildRequest
(
int
operationType
,
int
version
,
int
dataSize
,
String
key
,
int
crc
,
int
accessType
,
String
clientID
,
String
value
)
{
Request
.
Builder
request
=
Request
.
newBuilder
();
request
.
setOperationType
(
operationType
);
request
.
setVersion
(
version
);
request
.
setDataSize
(
dataSize
);
request
.
setKey
(
key
);
request
.
setCrc
(
crc
);
request
.
setAccessType
(
accessType
);
request
.
setClientID
(
clientID
);
request
.
setValue
(
value
);
return
request
.
build
();
}
public
static
Packet
buildPacket
(
ArrayList
<
Request
>
requests
)
{
Packet
.
Builder
packet
=
Packet
.
newBuilder
();
packet
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_REQUEST
);
packet
.
addAllRequest
(
requests
);
return
packet
.
build
();
}
}
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/java/HpdosClient/MessageFormat/ResponseBuilder.java
0 → 100644
View file @
f7053183
package
HpdosClient.MessageFormat
;
import
hpdos.grpc.*
;
import
java.util.ArrayList
;
public
class
ResponseBuilder
{
public
static
Ack
buildAck
(
int
version
,
int
dataSize
,
String
key
,
long
crc
,
String
value
)
{
Ack
.
Builder
ack
=
Ack
.
newBuilder
();
ack
.
setKey
(
key
);
ack
.
setVersion
(
version
);
ack
.
setDataSize
(
dataSize
);
ack
.
setCrc
(
crc
);
ack
.
setValue
(
value
);
return
ack
.
build
();
}
public
static
Nack
buildNack
(
int
version
,
String
key
)
{
Nack
.
Builder
nack
=
Nack
.
newBuilder
();
nack
.
setKey
(
key
);
nack
.
setVersion
(
version
);
return
nack
.
build
();
}
public
static
Response
buildResponsePacket
(
int
operationType
,
int
status
,
Ack
ack
,
Nack
nack
)
{
Response
.
Builder
response
=
Response
.
newBuilder
();
response
.
setOperationType
(
operationType
);
response
.
setStatus
(
status
);
if
(
ack
!=
null
)
response
.
setAck
(
ack
);
else
response
.
clearAck
();
if
(
nack
!=
null
)
response
.
setNack
(
nack
);
else
response
.
clearNack
();
return
response
.
build
();
}
public
static
Packet
buildPacket
(
ArrayList
<
Response
>
responses
)
{
Packet
.
Builder
packet
=
Packet
.
newBuilder
();
packet
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_RESPONSE
);
packet
.
addAllResponse
(
responses
);
return
packet
.
build
();
}
public
static
Packet
buildPacket
(
Response
response
)
{
Packet
.
Builder
packet
=
Packet
.
newBuilder
();
packet
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_RESPONSE
);
packet
.
addResponse
(
response
);
return
packet
.
build
();
}
}
code/lsm-tree-impl/host-app/hpdos_client/app/src/main/proto/PacketFormat.proto
0 → 100644
View file @
f7053183
syntax
=
"proto3"
;
package
hpdos
.
grpc
;
option
java_multiple_files
=
true
;
option
java_package
=
"hpdos.grpc"
;
option
java_outer_classname
=
"PacketFormatProto"
;
service
NetworkService
{
/**
Receive Packet from client
*/
rpc
readMetadata
(
Packet
)
returns
(
Packet
)
{}
rpc
createMetadata
(
Packet
)
returns
(
Packet
)
{}
rpc
updateMetadata
(
Packet
)
returns
(
Packet
)
{}
rpc
deleteMetadata
(
Packet
)
returns
(
Packet
)
{}
rpc
getReadReplicaList
(
RequestList
)
returns
(
ResponseList
)
{}
}
message
Packet
{
int32
packetType
=
1
;
repeated
Request
request
=
2
;
repeated
Response
response
=
3
;
}
message
Request
{
int32
operationType
=
1
;
int32
version
=
2
;
int32
dataSize
=
3
;
string
key
=
4
;
int64
crc
=
5
;
int32
accessType
=
6
;
string
clientID
=
7
;
string
value
=
8
;
}
message
Response
{
int32
operationType
=
1
;
int32
status
=
2
;
Ack
ack
=
3
;
Nack
nack
=
4
;
}
message
Ack
{
int32
version
=
2
;
int32
dataSize
=
3
;
string
key
=
4
;
int64
crc
=
5
;
string
value
=
6
;
}
message
Nack
{
string
key
=
2
;
int32
version
=
3
;
}
message
RequestList
{}
message
ResponseList
{
int32
operationType
=
1
;
int32
status
=
2
;
repeated
Follower
follower
=
3
;
}
message
Follower
{
string
ip
=
1
;
int32
port
=
2
;
string
followerID
=
3
;
int64
lastSeen
=
4
;
}
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_client/app/src/test/java/HpdosClient/AppTest.java
0 → 100644
View file @
f7053183
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package
HpdosClient
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
public
class
AppTest
{
@Test
public
void
testAppHasAGreeting
()
{
ClientRunner
classUnderTest
=
new
ClientRunner
();
assertNotNull
(
"app should have a greeting"
,
classUnderTest
.
getGreeting
());
}
}
code/lsm-tree-impl/host-app/hpdos_client/gradle/wrapper/gradle-wrapper.properties
0 → 100644
View file @
f7053183
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
code/lsm-tree-impl/host-app/hpdos_client/gradlew
0 → 100755
View file @
f7053183
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# 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
#
# https://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.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG
=
"
$0
"
# Need this for relative symlinks.
while
[
-h
"
$PRG
"
]
;
do
ls
=
`
ls
-ld
"
$PRG
"
`
link
=
`
expr
"
$ls
"
:
'.*-> \(.*\)$'
`
if
expr
"
$link
"
:
'/.*'
>
/dev/null
;
then
PRG
=
"
$link
"
else
PRG
=
`
dirname
"
$PRG
"
`
"/
$link
"
fi
done
SAVED
=
"
`
pwd
`
"
cd
"
`
dirname
\"
$PRG
\"
`
/"
>
/dev/null
APP_HOME
=
"
`
pwd
-P
`
"
cd
"
$SAVED
"
>
/dev/null
APP_NAME
=
"Gradle"
APP_BASE_NAME
=
`
basename
"
$0
"
`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS
=
'"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD
=
"maximum"
warn
()
{
echo
"
$*
"
}
die
()
{
echo
echo
"
$*
"
echo
exit
1
}
# OS specific support (must be 'true' or 'false').
cygwin
=
false
msys
=
false
darwin
=
false
nonstop
=
false
case
"
`
uname
`
"
in
CYGWIN
*
)
cygwin
=
true
;;
Darwin
*
)
darwin
=
true
;;
MINGW
*
)
msys
=
true
;;
NONSTOP
*
)
nonstop
=
true
;;
esac
CLASSPATH
=
$APP_HOME
/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if
[
-n
"
$JAVA_HOME
"
]
;
then
if
[
-x
"
$JAVA_HOME
/jre/sh/java"
]
;
then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD
=
"
$JAVA_HOME
/jre/sh/java"
else
JAVACMD
=
"
$JAVA_HOME
/bin/java"
fi
if
[
!
-x
"
$JAVACMD
"
]
;
then
die
"ERROR: JAVA_HOME is set to an invalid directory:
$JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD
=
"java"
which java
>
/dev/null 2>&1
||
die
"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if
[
"
$cygwin
"
=
"false"
-a
"
$darwin
"
=
"false"
-a
"
$nonstop
"
=
"false"
]
;
then
MAX_FD_LIMIT
=
`
ulimit
-H
-n
`
if
[
$?
-eq
0
]
;
then
if
[
"
$MAX_FD
"
=
"maximum"
-o
"
$MAX_FD
"
=
"max"
]
;
then
MAX_FD
=
"
$MAX_FD_LIMIT
"
fi
ulimit
-n
$MAX_FD
if
[
$?
-ne
0
]
;
then
warn
"Could not set maximum file descriptor limit:
$MAX_FD
"
fi
else
warn
"Could not query maximum file descriptor limit:
$MAX_FD_LIMIT
"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if
$darwin
;
then
GRADLE_OPTS
=
"
$GRADLE_OPTS
\"
-Xdock:name=
$APP_NAME
\"
\"
-Xdock:icon=
$APP_HOME
/media/gradle.icns
\"
"
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if
[
"
$cygwin
"
=
"true"
-o
"
$msys
"
=
"true"
]
;
then
APP_HOME
=
`
cygpath
--path
--mixed
"
$APP_HOME
"
`
CLASSPATH
=
`
cygpath
--path
--mixed
"
$CLASSPATH
"
`
JAVACMD
=
`
cygpath
--unix
"
$JAVACMD
"
`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW
=
`
find
-L
/
-maxdepth
1
-mindepth
1
-type
d 2>/dev/null
`
SEP
=
""
for
dir
in
$ROOTDIRSRAW
;
do
ROOTDIRS
=
"
$ROOTDIRS$SEP$dir
"
SEP
=
"|"
done
OURCYGPATTERN
=
"(^(
$ROOTDIRS
))"
# Add a user-defined pattern to the cygpath arguments
if
[
"
$GRADLE_CYGPATTERN
"
!=
""
]
;
then
OURCYGPATTERN
=
"
$OURCYGPATTERN
|(
$GRADLE_CYGPATTERN
)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i
=
0
for
arg
in
"
$@
"
;
do
CHECK
=
`
echo
"
$arg
"
|egrep
-c
"
$OURCYGPATTERN
"
-
`
CHECK2
=
`
echo
"
$arg
"
|egrep
-c
"^-"
`
### Determine if an option
if
[
$CHECK
-ne
0
]
&&
[
$CHECK2
-eq
0
]
;
then
### Added a condition
eval
`
echo
args
$i
`
=
`
cygpath
--path
--ignore
--mixed
"
$arg
"
`
else
eval
`
echo
args
$i
`
=
"
\"
$arg
\"
"
fi
i
=
`
expr
$i
+ 1
`
done
case
$i
in
0
)
set
--
;;
1
)
set
--
"
$args0
"
;;
2
)
set
--
"
$args0
"
"
$args1
"
;;
3
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
;;
4
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
;;
5
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
;;
6
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
;;
7
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
;;
8
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
"
$args7
"
;;
9
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
"
$args7
"
"
$args8
"
;;
esac
fi
# Escape application args
save
()
{
for
i
do
printf
%s
\\
n
"
$i
"
|
sed
"s/'/'
\\\\
''/g;1s/^/'/;
\$
s/
\$
/'
\\\\
/"
;
done
echo
" "
}
APP_ARGS
=
`
save
"
$@
"
`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set
--
$DEFAULT_JVM_OPTS
$JAVA_OPTS
$GRADLE_OPTS
"
\"
-Dorg.gradle.appname=
$APP_BASE_NAME
\"
"
-classpath
"
\"
$CLASSPATH
\"
"
org.gradle.wrapper.GradleWrapperMain
"
$APP_ARGS
"
exec
"
$JAVACMD
"
"
$@
"
code/lsm-tree-impl/host-app/hpdos_client/gradlew.bat
0 → 100644
View file @
f7053183
@rem
@rem
Copyright
2015
the
original
author
or
authors
.
@rem
@rem
Licensed
under
the
Apache
License
,
Version
2
.0
(
the
"License"
);
@rem
you
may
not
use
this
file
except
in
compliance
with
the
License
.
@rem
You
may
obtain
a
copy
of
the
License
at
@rem
@rem
https
://www.apache.org/licenses/LICENSE
-
2
.0
@rem
@rem
Unless
required
by
applicable
law
or
agreed
to
in
writing
,
software
@rem
distributed
under
the
License
is
distributed
on
an
"AS IS"
BASIS
,
@rem
WITHOUT
WARRANTIES
OR
CONDITIONS
OF
ANY
KIND
,
either
express
or
implied
.
@rem
See
the
License
for
the
specific
language
governing
permissions
and
@rem
limitations
under
the
License
.
@rem
@if
"
%DEBUG%
"
==
""
@echo
off
@rem ##########################################################################
@rem
@rem
Gradle
startup
script
for
Windows
@rem
@rem ##########################################################################
@rem
Set
local
scope
for
the
variables
with
windows
NT
shell
if
"
%OS%
"
==
"Windows_NT"
setlocal
set
DIRNAME
=
%~dp0
if
"
%DIRNAME%
"
==
""
set
DIRNAME
=
.
set
APP_BASE_NAME
=
%~n0
set
APP_HOME
=
%DIRNAME%
@rem
Resolve
any
"."
and
".."
in
APP_HOME
to
make
it
shorter
.
for
%%i
in
(
"
%APP_HOME%
"
)
do
set
APP_HOME
=
%%~fi
@rem
Add
default
JVM
options
here
.
You
can
also
use
JAVA_OPTS
and
GRADLE_OPTS
to
pass
JVM
options
to
this
script
.
set
DEFAULT_JVM_OPTS
=
"-Xmx64m"
"-Xms64m"
@rem
Find
java
.exe
if
defined
JAVA_HOME
goto
findJavaFromJavaHome
set
JAVA_EXE
=
java
.exe
%JAVA_EXE%
-version
>
NUL
2
>&
1
if
"
%ERRORLEVEL%
"
==
"0"
goto
execute
echo
.
echo
ERROR
:
JAVA_HOME
is
not
set
and
no
'java'
command
could
be
found
in
your
PATH
.
echo
.
echo
Please
set
the
JAVA_HOME
variable
in
your
environment
to
match
the
echo
location
of
your
Java
installation
.
goto
fail
:findJavaFromJavaHome
set
JAVA_HOME
=
%JAVA
_HOME:
"=
%
set JAVA_EXE=
%JAVA_HOME%
/bin/java.exe
if exist "
%JAVA_EXE%
" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory:
%JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
%APP_HOME%
\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"
%JAVA_EXE%
"
%DEFAULT_JVM_OPTS%
%JAVA_OPTS%
%GRADLE_OPTS%
"
-Dorg
.gradle.appname
=
%APP_BASE_NAME%
" -classpath "
%CLASSPATH%
" org.gradle.wrapper.GradleWrapperMain
%
*
:end
@rem End local scope for the variables with windows NT shell
if "
%ERRORLEVEL%
"=="
0
" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code
!
if not "" == "
%GRADLE_EXIT_CONSOLE%
" exit 1
exit /b 1
:mainEnd
if "
%OS%
"=="
Windows_NT
" endlocal
:omega
code/lsm-tree-impl/host-app/hpdos_client/settings.gradle
0 → 100644
View file @
f7053183
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/6.8.3/userguide/multi_project_builds.html
*/
rootProject
.
name
=
'HpdosClient'
include
(
'app'
)
code/lsm-tree-impl/host-app/hpdos_server/.idea/.gitignore
0 → 100644
View file @
f7053183
# Default ignored files
/shelf/
/workspace.xml
code/lsm-tree-impl/host-app/hpdos_server/.idea/.name
0 → 100644
View file @
f7053183
hpdos
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/.idea/compiler.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"CompilerConfiguration"
>
<bytecodeTargetLevel
target=
"14"
/>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/.idea/gradle.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"GradleMigrationSettings"
migrationVersion=
"1"
/>
<component
name=
"GradleSettings"
>
<option
name=
"linkedExternalProjectsSettings"
>
<GradleProjectSettings>
<option
name=
"delegatedBuild"
value=
"true"
/>
<option
name=
"testRunner"
value=
"GRADLE"
/>
<option
name=
"distributionType"
value=
"LOCAL"
/>
<option
name=
"externalProjectPath"
value=
"$PROJECT_DIR$"
/>
<option
name=
"gradleHome"
value=
"/usr/local/Cellar/gradle/6.8.3/libexec"
/>
<option
name=
"modules"
>
<set>
<option
value=
"$PROJECT_DIR$"
/>
<option
value=
"$PROJECT_DIR$/app"
/>
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/.idea/jarRepositories.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"RemoteRepositoriesConfiguration"
>
<remote-repository>
<option
name=
"id"
value=
"central"
/>
<option
name=
"name"
value=
"Maven Central repository"
/>
<option
name=
"url"
value=
"https://repo1.maven.org/maven2"
/>
</remote-repository>
<remote-repository>
<option
name=
"id"
value=
"jboss.community"
/>
<option
name=
"name"
value=
"JBoss Community repository"
/>
<option
name=
"url"
value=
"https://repository.jboss.org/nexus/content/repositories/public/"
/>
</remote-repository>
<remote-repository>
<option
name=
"id"
value=
"MavenRepo"
/>
<option
name=
"name"
value=
"MavenRepo"
/>
<option
name=
"url"
value=
"https://repo.maven.apache.org/maven2/"
/>
</remote-repository>
<remote-repository>
<option
name=
"id"
value=
"BintrayJCenter"
/>
<option
name=
"name"
value=
"BintrayJCenter"
/>
<option
name=
"url"
value=
"https://jcenter.bintray.com/"
/>
</remote-repository>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/.idea/misc.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"ExternalStorageConfigurationManager"
enabled=
"true"
/>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_14"
default=
"true"
project-jdk-name=
"14"
project-jdk-type=
"JavaSDK"
/>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/.idea/modules.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"ProjectModuleManager"
>
<modules>
<module
fileurl=
"file://$PROJECT_DIR$/.idea/hpdos_server.iml"
filepath=
"$PROJECT_DIR$/.idea/hpdos_server.iml"
/>
</modules>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/.idea/uiDesigner.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"Palette2"
>
<group
name=
"Swing"
>
<item
class=
"com.intellij.uiDesigner.HSpacer"
tooltip-text=
"Horizontal Spacer"
icon=
"/com/intellij/uiDesigner/icons/hspacer.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"1"
hsize-policy=
"6"
anchor=
"0"
fill=
"1"
/>
</item>
<item
class=
"com.intellij.uiDesigner.VSpacer"
tooltip-text=
"Vertical Spacer"
icon=
"/com/intellij/uiDesigner/icons/vspacer.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"1"
anchor=
"0"
fill=
"2"
/>
</item>
<item
class=
"javax.swing.JPanel"
icon=
"/com/intellij/uiDesigner/icons/panel.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"3"
hsize-policy=
"3"
anchor=
"0"
fill=
"3"
/>
</item>
<item
class=
"javax.swing.JScrollPane"
icon=
"/com/intellij/uiDesigner/icons/scrollPane.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"7"
hsize-policy=
"7"
anchor=
"0"
fill=
"3"
/>
</item>
<item
class=
"javax.swing.JButton"
icon=
"/com/intellij/uiDesigner/icons/button.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"3"
anchor=
"0"
fill=
"1"
/>
<initial-values>
<property
name=
"text"
value=
"Button"
/>
</initial-values>
</item>
<item
class=
"javax.swing.JRadioButton"
icon=
"/com/intellij/uiDesigner/icons/radioButton.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"3"
anchor=
"8"
fill=
"0"
/>
<initial-values>
<property
name=
"text"
value=
"RadioButton"
/>
</initial-values>
</item>
<item
class=
"javax.swing.JCheckBox"
icon=
"/com/intellij/uiDesigner/icons/checkBox.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"3"
anchor=
"8"
fill=
"0"
/>
<initial-values>
<property
name=
"text"
value=
"CheckBox"
/>
</initial-values>
</item>
<item
class=
"javax.swing.JLabel"
icon=
"/com/intellij/uiDesigner/icons/label.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"0"
anchor=
"8"
fill=
"0"
/>
<initial-values>
<property
name=
"text"
value=
"Label"
/>
</initial-values>
</item>
<item
class=
"javax.swing.JTextField"
icon=
"/com/intellij/uiDesigner/icons/textField.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
>
<preferred-size
width=
"150"
height=
"-1"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JPasswordField"
icon=
"/com/intellij/uiDesigner/icons/passwordField.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
>
<preferred-size
width=
"150"
height=
"-1"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JFormattedTextField"
icon=
"/com/intellij/uiDesigner/icons/formattedTextField.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
>
<preferred-size
width=
"150"
height=
"-1"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JTextArea"
icon=
"/com/intellij/uiDesigner/icons/textArea.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JTextPane"
icon=
"/com/intellij/uiDesigner/icons/textPane.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JEditorPane"
icon=
"/com/intellij/uiDesigner/icons/editorPane.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JComboBox"
icon=
"/com/intellij/uiDesigner/icons/comboBox.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"2"
anchor=
"8"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JTable"
icon=
"/com/intellij/uiDesigner/icons/table.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JList"
icon=
"/com/intellij/uiDesigner/icons/list.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"2"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JTree"
icon=
"/com/intellij/uiDesigner/icons/tree.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"150"
height=
"50"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JTabbedPane"
icon=
"/com/intellij/uiDesigner/icons/tabbedPane.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"3"
hsize-policy=
"3"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"200"
height=
"200"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JSplitPane"
icon=
"/com/intellij/uiDesigner/icons/splitPane.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"3"
hsize-policy=
"3"
anchor=
"0"
fill=
"3"
>
<preferred-size
width=
"200"
height=
"200"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JSpinner"
icon=
"/com/intellij/uiDesigner/icons/spinner.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"true"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JSlider"
icon=
"/com/intellij/uiDesigner/icons/slider.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"8"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JSeparator"
icon=
"/com/intellij/uiDesigner/icons/separator.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"6"
anchor=
"0"
fill=
"3"
/>
</item>
<item
class=
"javax.swing.JProgressBar"
icon=
"/com/intellij/uiDesigner/icons/progressbar.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"0"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JToolBar"
icon=
"/com/intellij/uiDesigner/icons/toolbar.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"6"
anchor=
"0"
fill=
"1"
>
<preferred-size
width=
"-1"
height=
"20"
/>
</default-constraints>
</item>
<item
class=
"javax.swing.JToolBar$Separator"
icon=
"/com/intellij/uiDesigner/icons/toolbarSeparator.png"
removable=
"false"
auto-create-binding=
"false"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"0"
hsize-policy=
"0"
anchor=
"0"
fill=
"1"
/>
</item>
<item
class=
"javax.swing.JScrollBar"
icon=
"/com/intellij/uiDesigner/icons/scrollbar.png"
removable=
"false"
auto-create-binding=
"true"
can-attach-label=
"false"
>
<default-constraints
vsize-policy=
"6"
hsize-policy=
"0"
anchor=
"0"
fill=
"2"
/>
</item>
</group>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/.idea/vcs.xml
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"VcsDirectoryMappings"
>
<mapping
directory=
"$PROJECT_DIR$/../.."
vcs=
"Git"
/>
</component>
</project>
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/app/.classpath
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry
kind=
"src"
output=
"bin/main"
path=
"src/main/java"
>
<attributes>
<attribute
name=
"gradle_scope"
value=
"main"
/>
<attribute
name=
"gradle_used_by_scope"
value=
"main,test"
/>
</attributes>
</classpathentry>
<classpathentry
kind=
"src"
output=
"bin/main"
path=
"src/main/resources"
>
<attributes>
<attribute
name=
"gradle_scope"
value=
"main"
/>
<attribute
name=
"gradle_used_by_scope"
value=
"main,test"
/>
</attributes>
</classpathentry>
<classpathentry
kind=
"src"
output=
"bin/test"
path=
"src/test/java"
>
<attributes>
<attribute
name=
"gradle_scope"
value=
"test"
/>
<attribute
name=
"gradle_used_by_scope"
value=
"test"
/>
<attribute
name=
"test"
value=
"true"
/>
</attributes>
</classpathentry>
<classpathentry
kind=
"src"
output=
"bin/test"
path=
"src/test/resources"
>
<attributes>
<attribute
name=
"gradle_scope"
value=
"test"
/>
<attribute
name=
"gradle_used_by_scope"
value=
"test"
/>
<attribute
name=
"test"
value=
"true"
/>
</attributes>
</classpathentry>
<classpathentry
kind=
"src"
output=
"bin/main"
path=
"build/generated/source/proto/main/java"
>
<attributes>
<attribute
name=
"gradle_scope"
value=
"main"
/>
<attribute
name=
"gradle_used_by_scope"
value=
"main,test"
/>
</attributes>
</classpathentry>
<classpathentry
kind=
"con"
path=
"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-14/"
/>
<classpathentry
kind=
"con"
path=
"org.eclipse.buildship.core.gradleclasspathcontainer"
/>
<classpathentry
kind=
"output"
path=
"bin/default"
/>
</classpath>
code/lsm-tree-impl/host-app/hpdos_server/app/.project
0 → 100644
View file @
f7053183
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>
app
</name>
<comment>
Project app created by Buildship.
</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>
org.eclipse.jdt.core.javabuilder
</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>
org.eclipse.buildship.core.gradleprojectbuilder
</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>
org.eclipse.jdt.core.javanature
</nature>
<nature>
org.eclipse.buildship.core.gradleprojectnature
</nature>
</natures>
<filteredResources>
<filter>
<id>
1617116007477
</id>
<name></name>
<type>
30
</type>
<matcher>
<id>
org.eclipse.core.resources.regexFilterMatcher
</id>
<arguments>
node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
code/lsm-tree-impl/host-app/hpdos_server/app/.settings/org.eclipse.buildship.core.prefs
0 → 100644
View file @
f7053183
connection.project.dir=..
eclipse.preferences.version=1
code/lsm-tree-impl/host-app/hpdos_server/app/build.gradle
0 → 100644
View file @
f7053183
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.8.3/userguide/building_java_projects.html
*/
plugins
{
// Apply the application plugin to add support for building a CLI application in Java.
id
'application'
id
"com.google.protobuf"
version
"0.8.15"
id
"java"
}
repositories
{
// Use JCenter for resolving dependencies.
jcenter
()
mavenCentral
()
}
dependencies
{
// Use JUnit test framework.
testImplementation
'junit:junit:4.13'
// This dependency is used by the application.
implementation
'com.google.guava:guava:29.0-jre'
implementation
group:
'com.google.protobuf'
,
name:
'protobuf-java'
,
version:
'3.15.6'
implementation
'io.grpc:grpc-netty-shaded:1.36.0'
implementation
'io.grpc:grpc-protobuf:1.36.0'
implementation
'io.grpc:grpc-stub:1.36.0'
compileOnly
'org.apache.tomcat:annotations-api:6.0.53'
// necessary for Java 9+
// https://mvnrepository.com/artifact/org.rocksdb/rocksdbjni
implementation
group:
'org.rocksdb'
,
name:
'rocksdbjni'
,
version:
'5.8.0'
// for object to byte array serialization
//compile 'org.apache.commons:commons-lang3:3.5'
}
application
{
// Define the main class for the application.
mainClass
=
'hpdos.MetadataServer'
}
sourceSets
{
src
{
main
{
java
{
srcDirs
'build/generated/source/proto/main/grpc'
srcDirs
'build/generated/source/proto/main/java'
}
}
}
}
protobuf
{
protoc
{
artifact
=
'com.google.protobuf:protoc:3.15.6'
}
plugins
{
grpc
{
artifact
=
"io.grpc:protoc-gen-grpc-java:1.36.0"
}
}
generateProtoTasks
{
all
()*.
plugins
{
grpc
{}
}
}
}
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/ConfigConstants.java
0 → 100644
View file @
f7053183
package
hpdos
;
public
class
ConfigConstants
{
public
static
final
boolean
DEBUG
=
false
;
public
static
final
String
HOST
=
"localhost"
;
public
static
final
int
PORT
=
8080
;
public
static
final
int
HEARTBEAT_INTERVAL
=
500
;
public
static
final
int
REPLICATION_TIMEOUT
=
5000
;
// Backend types 300-399
public
static
final
int
BACKEND_IN_MEMORY
=
300
;
public
static
final
int
LSM_BACKEND
=
301
;
public
static
final
int
BINARY_TREE_BACKEND
=
302
;
public
static
final
int
ROCKSDB_BACKEND
=
303
;
public
static
final
int
REPLICATOR_THREAD_POOL_SIZE
=
12
;
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/MetadataServer.java
0 → 100644
View file @
f7053183
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package
hpdos
;
import
hpdos.grpc.HeartbeatRequest
;
import
hpdos.grpc.HeartbeatResponse
;
import
hpdos.grpc.HeartbeatServiceGrpc
;
import
hpdos.handler.HeartbeatHandler
;
import
hpdos.handler.IOHandler
;
import
hpdos.handler.NetworkHandler
;
import
hpdos.handler.ReplicateHandler
;
import
hpdos.lib.*
;
import
hpdos.message.MessageConstants
;
import
io.grpc.ManagedChannel
;
import
io.grpc.ManagedChannelBuilder
;
import
io.grpc.Server
;
import
io.grpc.ServerBuilder
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
java.util.UUID
;
public
class
MetadataServer
{
private
Server
server
;
private
final
HashMap
<
String
,
MasterFollower
>
followers
;
private
final
String
serverID
;
private
boolean
isMaster
=
false
;
private
int
port
;
private
final
String
host
;
private
IOHandler
ioHandler
;
private
ReplicationService
replicationService
;
public
MetadataServer
()
{
this
.
followers
=
new
HashMap
<>();
this
.
serverID
=
UUID
.
randomUUID
().
toString
();
this
.
port
=
10000
+
(
int
)(
Math
.
random
()
*
40000
);
this
.
host
=
"localhost"
;
this
.
replicationService
=
null
;
}
public
String
getGreeting
()
{
return
"Hello World!"
;
}
public
boolean
startMasterServices
()
{
this
.
server
=
ServerBuilder
.
forPort
(
ConfigConstants
.
PORT
)
.
addService
(
new
NetworkHandler
(
this
.
ioHandler
,
this
.
replicationService
))
.
addService
(
new
HeartbeatHandler
(
followers
,
serverID
))
.
build
();
try
{
this
.
server
.
start
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
false
;
}
return
true
;
}
public
boolean
startFollowerServices
()
{
// In case of followers NetworkHandler will only serve read requests for private metadata
// Other network handler services will fail
this
.
server
=
ServerBuilder
.
forPort
(
port
)
.
addService
(
new
NetworkHandler
(
this
.
ioHandler
,
this
.
replicationService
))
.
addService
(
new
ReplicateHandler
(
this
.
ioHandler
))
.
build
();
try
{
this
.
server
.
start
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
false
;
}
return
true
;
}
public
void
blockForIO
(
Server
server
)
{
if
(
server
==
null
)
return
;
try
{
server
.
awaitTermination
();
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
private
void
announceToMaster
()
{
final
ManagedChannel
channel
=
ManagedChannelBuilder
.
forAddress
(
ConfigConstants
.
HOST
,
ConfigConstants
.
PORT
)
.
usePlaintext
()
.
build
();
HeartbeatServiceGrpc
.
HeartbeatServiceBlockingStub
stub
=
HeartbeatServiceGrpc
.
newBlockingStub
(
channel
);
HeartbeatRequest
.
Builder
heartbeat
=
HeartbeatRequest
.
newBuilder
();
heartbeat
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_REQUEST
);
heartbeat
.
setOperationType
(
MessageConstants
.
MASTER_HEARTBEAT
);
heartbeat
.
setFollowerID
(
this
.
serverID
);
heartbeat
.
setIp
(
this
.
host
);
heartbeat
.
setPort
(
this
.
port
);
try
{
HeartbeatResponse
response
=
stub
.
heartbeat
(
heartbeat
.
build
());
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Metadata Master not found, electing self as master"
);
this
.
isMaster
=
true
;
this
.
port
=
ConfigConstants
.
PORT
;
}
channel
.
shutdown
();
}
private
void
startHeartbeatService
()
{
Timer
timer
=
new
Timer
();
timer
.
scheduleAtFixedRate
(
new
TimerTask
()
{
@Override
public
void
run
()
{
announceToMaster
();
}
},
ConfigConstants
.
HEARTBEAT_INTERVAL
,
ConfigConstants
.
HEARTBEAT_INTERVAL
);
}
private
IOHandler
initStorage
(
int
backend
)
{
StorageService
storageService
;
switch
(
backend
)
{
case
ConfigConstants
.
BACKEND_IN_MEMORY
:
storageService
=
new
MemoryStorageService
();
break
;
case
ConfigConstants
.
ROCKSDB_BACKEND
:
storageService
=
new
RocksDBStorageService
();
// Uncomment the code below for local testing
/* StorageModel value = new StorageModel(1,5,"Hello",0,"A", "World");
storageService.create("Hello",value);
value = new StorageModel(1,5,"Hello",0,"A", "World");
storageService.update("Hello",value);
storageService.readByKey("Hello");
storageService.delete("Hello",value);*/
break
;
case
ConfigConstants
.
BINARY_TREE_BACKEND
:
case
ConfigConstants
.
LSM_BACKEND
:
default
:
return
null
;
}
return
new
IOHandler
(
storageService
,
this
.
isMaster
);
}
private
void
cleanup
()
{
if
(
this
.
replicationService
!=
null
)
{
try
{
this
.
replicationService
.
cleanup
();
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
main
(
String
[]
args
)
{
MetadataServer
metaDataServer
=
new
MetadataServer
();
System
.
out
.
println
(
metaDataServer
.
getGreeting
());
System
.
out
.
println
(
"Starting Metadata service"
);
System
.
out
.
println
(
"Initialising storage service"
);
// Check ConfigConstants for available storage options
//metaDataServer.ioHandler = metaDataServer.initStorage(ConfigConstants.BACKEND_IN_MEMORY);
metaDataServer
.
ioHandler
=
metaDataServer
.
initStorage
(
ConfigConstants
.
ROCKSDB_BACKEND
);
if
(
metaDataServer
.
ioHandler
==
null
)
{
System
.
out
.
println
(
"Storage server initialisation error"
);
return
;
}
System
.
out
.
println
(
"Searching for MetadataMaster"
);
metaDataServer
.
announceToMaster
();
if
(
metaDataServer
.
isMaster
)
{
metaDataServer
.
replicationService
=
new
InlineReplicationService
(
metaDataServer
.
followers
);
System
.
out
.
println
(
"Started master replication module"
);
boolean
status
=
metaDataServer
.
startMasterServices
();
System
.
out
.
println
(
"Master ID: "
+
metaDataServer
.
serverID
);
if
(
status
)
{
System
.
out
.
println
(
"Starting Master MetadataServer at: "
+
ConfigConstants
.
PORT
);
metaDataServer
.
blockForIO
(
metaDataServer
.
server
);
}
else
System
.
out
.
println
(
"Failed to create server"
);
}
else
{
System
.
out
.
println
(
"Master Node detected.\nStarting heartbeat service"
);
metaDataServer
.
startHeartbeatService
();
System
.
out
.
println
(
"Starting replication service"
);
boolean
status
=
metaDataServer
.
startFollowerServices
();
if
(
status
)
{
System
.
out
.
println
(
"Starting Follower MetadataServer at: "
+
metaDataServer
.
port
);
metaDataServer
.
blockForIO
(
metaDataServer
.
server
);
}
else
System
.
out
.
println
(
"Failed to create server"
);
}
// Adding a shutdown hook
Runtime
current
=
Runtime
.
getRuntime
();
current
.
addShutdownHook
(
new
Thread
(
metaDataServer:
:
cleanup
));
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/handler/HeartbeatHandler.java
0 → 100644
View file @
f7053183
package
hpdos.handler
;
import
hpdos.grpc.HeartbeatRequest
;
import
hpdos.grpc.HeartbeatResponse
;
import
hpdos.grpc.HeartbeatServiceGrpc
;
import
hpdos.lib.MasterFollower
;
import
hpdos.message.MessageConstants
;
import
io.grpc.stub.StreamObserver
;
import
java.time.Instant
;
import
java.util.HashMap
;
public
class
HeartbeatHandler
extends
HeartbeatServiceGrpc
.
HeartbeatServiceImplBase
{
private
final
HashMap
<
String
,
MasterFollower
>
followers
;
private
final
String
serverID
;
public
HeartbeatHandler
(
HashMap
<
String
,
MasterFollower
>
followers
,
String
serverID
)
{
this
.
followers
=
followers
;
this
.
serverID
=
serverID
;
}
@Override
public
void
heartbeat
(
HeartbeatRequest
request
,
StreamObserver
<
HeartbeatResponse
>
heartbeatResponseStreamObserver
)
{
if
(!
followers
.
containsKey
(
request
.
getFollowerID
()))
{
System
.
out
.
println
(
"New follower autodiscovery. Added to system "
+
request
);
followers
.
put
(
request
.
getFollowerID
(),
new
MasterFollower
(
request
.
getIp
(),
request
.
getPort
(),
request
.
getFollowerID
()));
}
else
{
MasterFollower
follower
=
followers
.
get
(
request
.
getFollowerID
());
follower
.
setLastSeen
(
Instant
.
now
().
getEpochSecond
());
}
HeartbeatResponse
.
Builder
response
=
HeartbeatResponse
.
newBuilder
();
response
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_RESPONSE
);
response
.
setOperationType
(
MessageConstants
.
MASTER_HEARTBEAT
);
response
.
setMasterID
(
this
.
serverID
);
heartbeatResponseStreamObserver
.
onNext
(
response
.
build
());
heartbeatResponseStreamObserver
.
onCompleted
();
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/handler/IOHandler.java
0 → 100644
View file @
f7053183
package
hpdos.handler
;
import
hpdos.grpc.Ack
;
import
hpdos.grpc.Nack
;
import
hpdos.grpc.Request
;
import
hpdos.grpc.Response
;
import
hpdos.lib.StorageModel
;
import
hpdos.lib.StorageService
;
import
hpdos.lib.StoredModel
;
import
hpdos.message.MessageConstants
;
import
hpdos.message.ResponseBuilder
;
public
class
IOHandler
{
StorageService
storageService
;
private
final
boolean
isMaster
;
public
IOHandler
(
StorageService
storageService
,
boolean
isMaster
)
{
this
.
storageService
=
storageService
;
this
.
isMaster
=
isMaster
;
}
public
Response
create
(
Request
request
)
{
Ack
ack
=
null
;
Nack
nack
=
null
;
StorageModel
blob
=
new
StorageModel
(
MessageConstants
.
INIT_VERSION
,
request
.
getDataSize
(),
request
.
getKey
(),
request
.
getAccessType
(),
request
.
getClientID
(),
request
.
getValue
());
StoredModel
storedData
=
storageService
.
create
(
request
.
getKey
(),
blob
);
if
(
storedData
.
getStatus
()
==
MessageConstants
.
STATUS_OK
)
{
ack
=
ResponseBuilder
.
buildAck
(
storedData
.
getData
().
getVersion
(),
storedData
.
getData
().
getDataSize
(),
storedData
.
getData
().
getKey
(),
storedData
.
getData
().
getCrc
(),
storedData
.
getData
().
getValue
());
return
ResponseBuilder
.
buildResponsePacket
(
MessageConstants
.
METADATA_CREATE
,
MessageConstants
.
STATUS_OK
,
ack
,
null
);
}
else
{
nack
=
ResponseBuilder
.
buildNack
(
MessageConstants
.
INVALID_VERSION
,
request
.
getKey
());
return
ResponseBuilder
.
buildResponsePacket
(
MessageConstants
.
METADATA_CREATE
,
storedData
.
getStatus
(),
null
,
nack
);
}
}
public
Response
update
(
Request
request
)
{
Ack
ack
=
null
;
Nack
nack
=
null
;
StorageModel
blob
=
new
StorageModel
(
request
.
getVersion
(),
request
.
getDataSize
(),
request
.
getKey
(),
request
.
getAccessType
(),
request
.
getClientID
(),
request
.
getValue
());
StoredModel
storedData
=
storageService
.
update
(
request
.
getKey
(),
blob
);
if
(
storedData
.
getStatus
()
==
MessageConstants
.
STATUS_OK
)
{
ack
=
ResponseBuilder
.
buildAck
(
storedData
.
getData
().
getVersion
(),
storedData
.
getData
().
getDataSize
(),
storedData
.
getData
().
getKey
(),
storedData
.
getData
().
getCrc
(),
storedData
.
getData
().
getValue
());
return
ResponseBuilder
.
buildResponsePacket
(
MessageConstants
.
METADATA_CREATE
,
MessageConstants
.
STATUS_OK
,
ack
,
null
);
}
else
{
int
version
=
(
storedData
.
getStatus
()
==
MessageConstants
.
STATUS_UPDATE_VERSION_MISMATCH
)?
storedData
.
getData
().
getVersion
():
MessageConstants
.
INVALID_VERSION
;
nack
=
ResponseBuilder
.
buildNack
(
version
,
request
.
getKey
());
return
ResponseBuilder
.
buildResponsePacket
(
MessageConstants
.
METADATA_CREATE
,
storedData
.
getStatus
(),
null
,
nack
);
}
}
/**
* Removes the object from the KV store if the request version matches with the current version of data
* @param request Models to be deleted. Only the key, clientID and version needs to be valid
* @return previous value if successful else null with status
*/
public
Response
delete
(
Request
request
)
{
Ack
ack
=
null
;
Nack
nack
=
null
;
StorageModel
blob
=
new
StorageModel
(
request
.
getVersion
(),
request
.
getDataSize
(),
request
.
getKey
(),
request
.
getAccessType
(),
request
.
getClientID
(),
request
.
getValue
());
StoredModel
storedData
=
storageService
.
delete
(
request
.
getKey
(),
blob
);
if
(
storedData
.
getStatus
()
==
MessageConstants
.
STATUS_OK
)
{
ack
=
ResponseBuilder
.
buildAck
(
storedData
.
getData
().
getVersion
(),
storedData
.
getData
().
getDataSize
(),
storedData
.
getData
().
getKey
(),
storedData
.
getData
().
getCrc
(),
storedData
.
getData
().
getValue
());
return
ResponseBuilder
.
buildResponsePacket
(
MessageConstants
.
METADATA_CREATE
,
MessageConstants
.
STATUS_OK
,
ack
,
null
);
}
else
{
int
version
=
(
storedData
.
getStatus
()
==
MessageConstants
.
STATUS_UPDATE_VERSION_MISMATCH
)?
storedData
.
getData
().
getVersion
():
MessageConstants
.
INVALID_VERSION
;
nack
=
ResponseBuilder
.
buildNack
(
version
,
request
.
getKey
());
return
ResponseBuilder
.
buildResponsePacket
(
MessageConstants
.
METADATA_CREATE
,
storedData
.
getStatus
(),
null
,
nack
);
}
}
public
Response
read
(
Request
request
)
{
Ack
ack
=
null
;
Nack
nack
=
null
;
int
status
;
// Only Metadata Master can serve shared object lookup requests
if
(!
isMaster
&&
request
.
getAccessType
()
==
MessageConstants
.
METADATA_ACCESS_SHARED
)
{
status
=
MessageConstants
.
STATUS_SERVER_NOT_MASTER
;
nack
=
ResponseBuilder
.
buildNack
(
MessageConstants
.
INVALID_VERSION
,
request
.
getKey
());
}
else
{
StoredModel
readData
=
storageService
.
readByKey
(
request
.
getKey
());
if
(
readData
.
getStatus
()
==
MessageConstants
.
STATUS_KEY_NOT_FOUND
)
{
status
=
MessageConstants
.
STATUS_KEY_NOT_FOUND
;
nack
=
ResponseBuilder
.
buildNack
(
MessageConstants
.
INVALID_VERSION
,
request
.
getKey
());
}
else
if
(
readData
.
getData
().
getAccessType
()
==
MessageConstants
.
METADATA_ACCESS_PRIVATE
&&
!
request
.
getClientID
().
equals
(
readData
.
getData
().
getOwner
()))
{
status
=
MessageConstants
.
STATUS_UNAUTHORIZED_PRIVATE_KEY_ACCESS
;
nack
=
ResponseBuilder
.
buildNack
(
MessageConstants
.
INVALID_VERSION
,
request
.
getKey
());
}
else
{
status
=
MessageConstants
.
STATUS_OK
;
ack
=
ResponseBuilder
.
buildAck
(
readData
.
getData
().
getVersion
(),
readData
.
getData
().
getDataSize
(),
readData
.
getData
().
getKey
(),
readData
.
getData
().
getCrc
(),
readData
.
getData
().
getValue
());
}
}
return
ResponseBuilder
.
buildResponsePacket
(
MessageConstants
.
METADATA_CREATE
,
status
,
ack
,
nack
);
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/handler/NetworkHandler.java
0 → 100644
View file @
f7053183
package
hpdos.handler
;
import
com.google.common.base.Stopwatch
;
import
hpdos.grpc.*
;
import
hpdos.lib.MasterFollower
;
import
hpdos.lib.ReplicationService
;
import
hpdos.message.RequestBuilder
;
import
hpdos.message.ResponseBuilder
;
import
io.grpc.stub.StreamObserver
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.concurrent.ExecutionException
;
public
class
NetworkHandler
extends
NetworkServiceGrpc
.
NetworkServiceImplBase
{
private
final
IOHandler
ioHandler
;
private
final
ReplicationService
replicationService
;
public
NetworkHandler
(
IOHandler
ioHandler
,
ReplicationService
replicationService
)
{
this
.
ioHandler
=
ioHandler
;
this
.
replicationService
=
replicationService
;
}
@Override
public
void
readMetadata
(
Packet
requestPacket
,
StreamObserver
<
Packet
>
responseObserver
)
{
// System.out.println("Data received" + requestPacket.toString());
for
(
Request
request:
requestPacket
.
getRequestList
())
{
Response
response
=
ioHandler
.
read
(
request
);
Packet
packet
=
ResponseBuilder
.
buildPacket
(
response
);
// System.out.println(packet);
responseObserver
.
onNext
(
packet
);
}
responseObserver
.
onCompleted
();
}
@Override
public
void
createMetadata
(
Packet
requestPacket
,
StreamObserver
<
Packet
>
responseObserver
)
{
Stopwatch
stopwatch
=
Stopwatch
.
createUnstarted
();
stopwatch
.
start
();
for
(
Request
request:
requestPacket
.
getRequestList
())
{
ioHandler
.
create
(
request
);
}
stopwatch
.
stop
();
// System.out.println("Added to local memory " + stopwatch);
stopwatch
.
reset
();
stopwatch
.
start
();
Packet
packet
=
replicate
(
requestPacket
);
stopwatch
.
stop
();
// System.out.println("Replication time " + stopwatch);
responseObserver
.
onNext
(
packet
);
responseObserver
.
onCompleted
();
}
@Override
public
void
updateMetadata
(
Packet
requestPacket
,
StreamObserver
<
Packet
>
responseObserver
)
{
// System.out.println("new create request " + requestPacket);
for
(
Request
request:
requestPacket
.
getRequestList
())
{
ioHandler
.
update
(
request
);
}
// System.out.println("Added to local memory");
Packet
packet
=
replicate
(
requestPacket
);
responseObserver
.
onNext
(
packet
);
responseObserver
.
onCompleted
();
}
@Override
public
void
deleteMetadata
(
Packet
requestPacket
,
StreamObserver
<
Packet
>
responseObserver
)
{
// System.out.println("new create request " + requestPacket);
for
(
Request
request:
requestPacket
.
getRequestList
())
{
ioHandler
.
delete
(
request
);
}
// System.out.println("Added to local memory");
Packet
packet
=
replicate
(
requestPacket
);
responseObserver
.
onNext
(
packet
);
responseObserver
.
onCompleted
();
}
@Override
public
void
getReadReplicaList
(
RequestList
requestList
,
StreamObserver
<
ResponseList
>
responseListStreamObserver
)
{
HashMap
<
String
,
MasterFollower
>
followers
=
replicationService
.
getFollowers
();
ResponseList
.
Builder
responseList
=
ResponseList
.
newBuilder
();
for
(
MasterFollower
follower:
followers
.
values
())
{
Follower
.
Builder
replica
=
Follower
.
newBuilder
();
replica
.
setIp
(
follower
.
getIp
());
replica
.
setPort
(
follower
.
getPort
());
replica
.
setFollowerID
(
follower
.
getFollowerID
());
replica
.
setLastSeen
(
follower
.
getLastSeen
());
replica
.
build
();
responseList
.
addFollower
(
replica
);
}
responseListStreamObserver
.
onNext
(
responseList
.
build
());
responseListStreamObserver
.
onCompleted
();
}
private
Packet
replicate
(
Packet
requestPacket
)
{
ReplicationRequest
replicationRequest
=
RequestBuilder
.
buildReplicationRequest
(
new
ArrayList
<>(
requestPacket
.
getRequestList
()));
ReplicationResponse
replicationResponse
=
null
;
try
{
// System.out.println("starting replication");
Stopwatch
stopwatch
=
Stopwatch
.
createUnstarted
();
stopwatch
.
start
();
replicationResponse
=
replicationService
.
replicateMetadata
(
replicationRequest
);
stopwatch
.
stop
();
// System.out.println("Network handler replicate" + stopwatch);
}
catch
(
InterruptedException
|
ExecutionException
e
)
{
e
.
printStackTrace
();
}
// System.out.println("replication complete");
Packet
packet
=
ResponseBuilder
.
buildPacket
(
new
ArrayList
<>(
replicationResponse
.
getResponseList
()));
// System.out.println(packet);
return
packet
;
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/handler/ReplicateHandler.java
0 → 100644
View file @
f7053183
package
hpdos.handler
;
import
com.google.common.base.Stopwatch
;
import
hpdos.grpc.*
;
import
hpdos.message.MessageConstants
;
import
hpdos.message.ResponseBuilder
;
import
io.grpc.stub.StreamObserver
;
public
class
ReplicateHandler
extends
ReplicationServiceGrpc
.
ReplicationServiceImplBase
{
private
final
IOHandler
ioHandler
;
public
ReplicateHandler
(
IOHandler
ioHandler
)
{
this
.
ioHandler
=
ioHandler
;
}
@Override
public
void
replicateMetadata
(
ReplicationRequest
replicationRequest
,
StreamObserver
<
ReplicationResponse
>
responseObserver
)
{
ReplicationResponse
responsePacket
=
null
;
// System.out.println("Replication request " + replicationRequest);
Stopwatch
stopwatch
=
Stopwatch
.
createUnstarted
();
stopwatch
.
start
();
if
(
replicationRequest
.
getPacketType
()
==
MessageConstants
.
PACKET_METADATA_REQUEST
)
{
for
(
Request
request:
replicationRequest
.
getRequestList
())
{
if
(
request
.
getOperationType
()
==
MessageConstants
.
METADATA_CREATE
)
{
Response
response
=
ioHandler
.
create
(
request
);
responsePacket
=
ResponseBuilder
.
buildReplicationResponse
(
response
);
}
else
if
(
request
.
getOperationType
()
==
MessageConstants
.
METADATA_UPDATE
)
{
Response
response
=
ioHandler
.
update
(
request
);
responsePacket
=
ResponseBuilder
.
buildReplicationResponse
(
response
);
}
else
if
(
request
.
getOperationType
()
==
MessageConstants
.
METADATA_DELETE
)
{
Response
response
=
ioHandler
.
delete
(
request
);
responsePacket
=
ResponseBuilder
.
buildReplicationResponse
(
response
);
}
responseObserver
.
onNext
(
responsePacket
);
}
responseObserver
.
onCompleted
();
}
stopwatch
.
stop
();
// System.out.println("Replicate Handler " + stopwatch);
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/InlineReplicationService.java
0 → 100644
View file @
f7053183
package
hpdos.lib
;
import
com.google.common.base.Stopwatch
;
import
com.google.common.util.concurrent.ListenableFuture
;
import
hpdos.ConfigConstants
;
import
hpdos.grpc.ReplicationRequest
;
import
hpdos.grpc.ReplicationResponse
;
import
hpdos.grpc.ReplicationServiceGrpc
;
import
hpdos.grpc.Response
;
import
hpdos.message.MessageConstants
;
import
hpdos.message.ResponseBuilder
;
import
io.grpc.ManagedChannel
;
import
io.grpc.ManagedChannelBuilder
;
import
java.util.*
;
import
java.util.concurrent.*
;
public
class
InlineReplicationService
implements
ReplicationService
{
private
final
HashMap
<
String
,
MasterFollower
>
followers
;
private
final
HashMap
<
String
,
ManagedChannel
>
channels
;
private
final
ExecutorService
executorService
;
public
InlineReplicationService
(
HashMap
<
String
,
MasterFollower
>
followers
)
{
this
.
followers
=
followers
;
this
.
channels
=
new
HashMap
<>();
for
(
MasterFollower
follower:
this
.
followers
.
values
())
{
ManagedChannel
channel
=
ManagedChannelBuilder
.
forAddress
(
follower
.
getIp
(),
follower
.
getPort
())
.
usePlaintext
()
.
build
();
channels
.
put
(
follower
.
getFollowerID
(),
channel
);
}
this
.
executorService
=
Executors
.
newFixedThreadPool
(
ConfigConstants
.
REPLICATOR_THREAD_POOL_SIZE
);
}
@Override
public
void
cleanup
()
throws
InterruptedException
{
for
(
ManagedChannel
channel:
channels
.
values
())
channel
.
shutdown
();
executorService
.
shutdown
();
executorService
.
awaitTermination
(
MessageConstants
.
STATUS_REPLICATION_TIMEOUT
,
TimeUnit
.
MILLISECONDS
);
}
private
void
establishChannels
()
{
for
(
String
followerID:
followers
.
keySet
())
{
if
(!
channels
.
containsKey
(
followerID
))
{
MasterFollower
follower
=
followers
.
get
(
followerID
);
ManagedChannel
channel
=
ManagedChannelBuilder
.
forAddress
(
follower
.
getIp
(),
follower
.
getPort
())
.
usePlaintext
()
.
build
();
channels
.
put
(
follower
.
getFollowerID
(),
channel
);
}
}
}
@Override
public
ReplicationResponse
replicateMetadata
(
ReplicationRequest
replicationRequest
)
throws
InterruptedException
,
ExecutionException
{
Set
<
Callable
<
ReplicationResponse
>>
callables
=
new
HashSet
<>();
// new followers have joined or left.
// TODO: Handle follower leaving scenario
// FIXME: fix edge case where equal number of followers leaving and joining won't trigger connection reestablishment
if
(
channels
.
size
()
!=
followers
.
size
())
{
establishChannels
();
}
for
(
ManagedChannel
channel:
channels
.
values
())
{
callables
.
add
(()
->
{
ReplicationServiceGrpc
.
ReplicationServiceBlockingStub
stub
=
ReplicationServiceGrpc
.
newBlockingStub
(
channel
);
return
stub
.
replicateMetadata
(
replicationRequest
);
});
}
List
<
Future
<
ReplicationResponse
>>
futures
=
executorService
.
invokeAll
(
callables
);
HashMap
<
String
,
Response
>
responseHashMap
=
new
HashMap
<>();
Stopwatch
stopwatch
=
Stopwatch
.
createUnstarted
();
stopwatch
.
start
();
for
(
Future
<
ReplicationResponse
>
future:
futures
)
{
ReplicationResponse
replicationResponse
;
replicationResponse
=
future
.
get
();
//TODO: Add and handle get timeout. Timeout related constants already added
for
(
Response
receivedResponse:
replicationResponse
.
getResponseList
())
{
int
status
=
receivedResponse
.
getStatus
();
if
(
status
==
MessageConstants
.
STATUS_OK
)
{
if
(!
responseHashMap
.
containsKey
(
receivedResponse
.
getAck
().
getKey
()))
responseHashMap
.
put
(
receivedResponse
.
getAck
().
getKey
(),
receivedResponse
);
}
else
{
responseHashMap
.
put
(
receivedResponse
.
getNack
().
getKey
(),
receivedResponse
);
}
}
}
stopwatch
.
stop
();
// System.out.println("replicateMetadata ReplicationService " + stopwatch);
return
ResponseBuilder
.
buildReplicationResponse
(
new
ArrayList
<>(
responseHashMap
.
values
()));
}
@Override
public
ReplicationResponse
replicateMetadataAsync
(
ReplicationRequest
replicationRequest
)
{
for
(
ManagedChannel
channel:
channels
.
values
())
{
ReplicationServiceGrpc
.
ReplicationServiceFutureStub
stub
=
ReplicationServiceGrpc
.
newFutureStub
(
channel
);
ListenableFuture
<
ReplicationResponse
>
res
=
stub
.
replicateMetadata
(
replicationRequest
);
}
throw
new
UnsupportedOperationException
(
"Implementation not complete"
);
}
@Override
public
HashMap
<
String
,
MasterFollower
>
getFollowers
()
{
return
followers
;
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/MasterFollower.java
0 → 100644
View file @
f7053183
package
hpdos.lib
;
import
java.time.Instant
;
public
class
MasterFollower
{
private
String
ip
;
private
int
port
;
private
final
String
followerID
;
private
long
lastSeen
;
public
MasterFollower
(
String
ip
,
int
port
,
String
followerID
)
{
this
.
ip
=
ip
;
this
.
port
=
port
;
this
.
followerID
=
followerID
;
this
.
lastSeen
=
Instant
.
now
().
getEpochSecond
();
}
public
String
getIp
()
{
return
ip
;
}
public
void
setIp
(
String
ip
)
{
this
.
ip
=
ip
;
}
public
int
getPort
()
{
return
port
;
}
public
void
setPort
(
int
port
)
{
this
.
port
=
port
;
}
public
String
getFollowerID
()
{
return
followerID
;
}
public
long
getLastSeen
()
{
return
lastSeen
;
}
public
void
setLastSeen
(
long
lastSeen
)
{
this
.
lastSeen
=
lastSeen
;
}
@Override
public
String
toString
()
{
return
"MasterFollower {"
+
"ip='"
+
ip
+
'\''
+
", port="
+
port
+
", followerID='"
+
followerID
+
'\''
+
'}'
;
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/MemoryStorageService.java
0 → 100644
View file @
f7053183
package
hpdos.lib
;
import
hpdos.message.MessageConstants
;
import
java.util.concurrent.ConcurrentHashMap
;
public
class
MemoryStorageService
implements
StorageService
{
private
final
ConcurrentHashMap
<
String
,
StorageModel
>
memoryKVStore
;
public
MemoryStorageService
()
{
this
.
memoryKVStore
=
new
ConcurrentHashMap
<>();
}
@Override
public
StoredModel
create
(
String
key
,
StorageModel
value
)
{
try
{
if
(
memoryKVStore
.
putIfAbsent
(
key
,
value
)
!=
null
)
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_KEY_EXISTS
);
return
new
StoredModel
(
value
,
MessageConstants
.
STATUS_OK
);
}
catch
(
Exception
e
)
{
return
null
;
}
}
@Override
public
StoredModel
readByKey
(
String
key
)
{
if
(!
memoryKVStore
.
containsKey
(
key
))
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_KEY_NOT_FOUND
);
return
new
StoredModel
(
memoryKVStore
.
get
(
key
),
MessageConstants
.
STATUS_OK
);
}
@Override
public
StoredModel
update
(
String
key
,
StorageModel
value
)
{
StorageModel
previousValue
=
memoryKVStore
.
get
(
key
);
if
(
previousValue
==
null
)
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_KEY_NOT_FOUND
);
else
if
(
previousValue
.
getAccessType
()
==
MessageConstants
.
METADATA_ACCESS_PRIVATE
&&
!
previousValue
.
getOwner
().
equals
(
value
.
getOwner
()))
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_UNAUTHORIZED_PRIVATE_KEY_ACCESS
);
// the request will have the old version number of the data to be inserted, we only update the data
// with a new version number if at the time of update the two versions match
// else we reject the update
StorageModel
newValue
=
value
.
createVersionUpdatedModel
();
boolean
status
=
memoryKVStore
.
replace
(
key
,
value
,
newValue
);
// the equals method is overridden in Storage model
// to equate two objects based on their version numbers
if
(
status
)
return
new
StoredModel
(
value
,
MessageConstants
.
STATUS_OK
);
else
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_UPDATE_VERSION_MISMATCH
);
}
@Override
public
StoredModel
delete
(
String
key
,
StorageModel
value
)
{
StorageModel
previousValue
=
memoryKVStore
.
get
(
key
);
if
(
previousValue
==
null
)
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_KEY_NOT_FOUND
);
else
if
(
previousValue
.
getAccessType
()
==
MessageConstants
.
METADATA_ACCESS_PRIVATE
&&
!
previousValue
.
getOwner
().
equals
(
value
.
getOwner
()))
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_UNAUTHORIZED_PRIVATE_KEY_ACCESS
);
boolean
status
=
memoryKVStore
.
remove
(
key
,
value
);
if
(
status
)
return
new
StoredModel
(
previousValue
,
MessageConstants
.
STATUS_OK
);
else
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_UPDATE_VERSION_MISMATCH
);
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/ReplicationService.java
0 → 100644
View file @
f7053183
package
hpdos.lib
;
import
hpdos.grpc.ReplicationRequest
;
import
hpdos.grpc.ReplicationResponse
;
import
java.util.HashMap
;
import
java.util.concurrent.ExecutionException
;
public
interface
ReplicationService
{
abstract
ReplicationResponse
replicateMetadata
(
ReplicationRequest
replicationRequest
)
throws
InterruptedException
,
ExecutionException
;
abstract
ReplicationResponse
replicateMetadataAsync
(
ReplicationRequest
replicationRequest
);
abstract
void
cleanup
()
throws
InterruptedException
;
abstract
HashMap
<
String
,
MasterFollower
>
getFollowers
();
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/RocksDBStorageService.java
0 → 100644
View file @
f7053183
package
hpdos.lib
;
import
hpdos.ConfigConstants
;
import
hpdos.message.MessageConstants
;
import
org.rocksdb.Options
;
import
org.rocksdb.RocksDB
;
import
org.rocksdb.RocksDBException
;
import
java.io.*
;
public
class
RocksDBStorageService
implements
StorageService
{
//private final ConcurrentHashMap<String, StorageModel> memoryKVStore;
private
static
final
String
dbPath
=
"./rocksdb-data/"
;
private
RocksDB
rocksDB
;
public
RocksDBStorageService
()
{
//this.memoryKVStore = new ConcurrentHashMap<>();
RocksDB
.
loadLibrary
();
//If the file does not exist, create the file first
try
(
final
Options
options
=
new
Options
().
setCreateIfMissing
(
true
))
{
try
{
rocksDB
=
RocksDB
.
open
(
options
,
dbPath
);
options
.
useDirectReads
();
options
.
setIncreaseParallelism
(
12
);
//options.writeBufferSize(); //16GB
//options.optimizeForPointLookup(256);
}
catch
(
RocksDBException
e
)
{
e
.
printStackTrace
();
}
}
System
.
out
.
println
(
"Persistent Store Opened Successfully!"
);
}
public
static
byte
[]
toStream
(
StorageModel
val
)
{
// Reference for stream of bytes
if
(
val
==
null
)
return
null
;
byte
[]
stream
=
null
;
// ObjectOutputStream is used to convert a Java object into OutputStream
try
(
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
ObjectOutputStream
oos
=
new
ObjectOutputStream
(
baos
))
{
oos
.
writeObject
(
val
);
stream
=
baos
.
toByteArray
();
}
catch
(
IOException
e
)
{
// Error in serialization
e
.
printStackTrace
();
}
return
stream
;
}
public
static
StorageModel
toStorageModel
(
byte
[]
stream
)
{
StorageModel
st
=
null
;
if
(
stream
==
null
)
return
null
;
try
(
ByteArrayInputStream
bais
=
new
ByteArrayInputStream
(
stream
);
ObjectInputStream
ois
=
new
ObjectInputStream
(
bais
))
{
st
=
(
StorageModel
)
ois
.
readObject
();
}
catch
(
IOException
|
ClassNotFoundException
e
)
{
// Error in de-serialization
e
.
printStackTrace
();
}
// You are converting an invalid stream to StorageModel
return
st
;
}
@Override
public
StoredModel
create
(
String
key
,
StorageModel
value
)
{
/* try {
if (memoryKVStore.putIfAbsent(key, value) != null)
return new StoredModel(null, MessageConstants.STATUS_KEY_EXISTS);
return new StoredModel(value, MessageConstants.STATUS_OK);
} catch (Exception e) {
return null;
}*/
try
{
if
(
rocksDB
.
get
(
key
.
getBytes
())
==
null
)
{
rocksDB
.
put
(
key
.
getBytes
(),
toStream
(
value
));
if
(
ConfigConstants
.
DEBUG
)
{
System
.
out
.
println
(
"Created object with key = "
+
key
);
}
//return new StoredModel(value, MessageConstants.STATUS_OK);
}
else
{
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_KEY_EXISTS
);
}
}
catch
(
RocksDBException
e
)
{
e
.
printStackTrace
();
}
return
new
StoredModel
(
value
,
MessageConstants
.
STATUS_OK
);
}
@Override
public
StoredModel
readByKey
(
String
key
)
{
/*if (!memoryKVStore.containsKey(key))
return new StoredModel(null, MessageConstants.STATUS_KEY_NOT_FOUND);
return new StoredModel(memoryKVStore.get(key), MessageConstants.STATUS_OK);*/
StorageModel
tmpStorageModel
=
null
;
try
{
tmpStorageModel
=
toStorageModel
(
rocksDB
.
get
(
key
.
getBytes
()));
if
(
tmpStorageModel
==
null
)
{
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_KEY_NOT_FOUND
);
}
}
catch
(
RocksDBException
e
)
{
e
.
printStackTrace
();
}
return
new
StoredModel
(
tmpStorageModel
,
MessageConstants
.
STATUS_OK
);
}
@Override
public
StoredModel
update
(
String
key
,
StorageModel
value
)
{
/* StorageModel previousValue = memoryKVStore.get(key);
if (previousValue == null)
return new StoredModel(null, MessageConstants.STATUS_KEY_NOT_FOUND);
else if (previousValue.getAccessType() == MessageConstants.METADATA_ACCESS_PRIVATE
&& !previousValue.getOwner().equals(value.getOwner()))
return new StoredModel(null, MessageConstants.STATUS_UNAUTHORIZED_PRIVATE_KEY_ACCESS);
// the request will have the old version number of the data to be inserted, we only update the data
// with a new version number if at the time of update the two versions match
// else we reject the update
StorageModel newValue = value.createVersionUpdatedModel();
boolean status = memoryKVStore.replace(key, value, newValue); // the equals method is overridden in Storage model
// to equate two objects based on their version numbers
if (status)
return new StoredModel(value, MessageConstants.STATUS_OK);
else
return new StoredModel(null, MessageConstants.STATUS_UPDATE_VERSION_MISMATCH);*/
StorageModel
previousValue
;
boolean
status
=
false
;
try
{
previousValue
=
toStorageModel
(
rocksDB
.
get
(
key
.
getBytes
()));
if
(
previousValue
==
null
)
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_KEY_NOT_FOUND
);
else
if
(
previousValue
.
getAccessType
()
==
MessageConstants
.
METADATA_ACCESS_PRIVATE
&&
!
previousValue
.
getOwner
().
equals
(
value
.
getOwner
()))
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_UNAUTHORIZED_PRIVATE_KEY_ACCESS
);
// the request will have the old version number of the data to be inserted, we only update the data
// with a new version number if at the time of update the two versions match
// else we reject the update
StorageModel
newValue
=
value
.
createVersionUpdatedModel
();
if
(
newValue
.
getVersion
()
>
previousValue
.
getVersion
())
{
status
=
true
;
rocksDB
.
put
(
key
.
getBytes
(),
toStream
(
value
));
if
(
ConfigConstants
.
DEBUG
)
{
System
.
out
.
println
(
"Updated object with key = "
+
key
);
}
}
}
catch
(
RocksDBException
e
)
{
e
.
printStackTrace
();
}
if
(
status
)
return
new
StoredModel
(
value
,
MessageConstants
.
STATUS_OK
);
else
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_UPDATE_VERSION_MISMATCH
);
}
@Override
public
StoredModel
delete
(
String
key
,
StorageModel
value
)
{
/*StorageModel previousValue = memoryKVStore.get(key);
if (previousValue == null)
return new StoredModel(null, MessageConstants.STATUS_KEY_NOT_FOUND);
else if (previousValue.getAccessType() == MessageConstants.METADATA_ACCESS_PRIVATE
&& !previousValue.getOwner().equals(value.getOwner()))
return new StoredModel(null, MessageConstants.STATUS_UNAUTHORIZED_PRIVATE_KEY_ACCESS);
boolean status = memoryKVStore.remove(key, value);
if (status)
return new StoredModel(previousValue, MessageConstants.STATUS_OK);
else
return new StoredModel(null, MessageConstants.STATUS_UPDATE_VERSION_MISMATCH);
}*/
StorageModel
previousValue
=
null
;
//boolean status = false;
try
{
previousValue
=
toStorageModel
(
rocksDB
.
get
(
key
.
getBytes
()));
if
(
previousValue
==
null
)
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_KEY_NOT_FOUND
);
else
{
if
(
previousValue
.
getAccessType
()
==
MessageConstants
.
METADATA_ACCESS_PRIVATE
&&
!
previousValue
.
getOwner
().
equals
(
value
.
getOwner
()))
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_UNAUTHORIZED_PRIVATE_KEY_ACCESS
);
if
(
value
.
getVersion
()
<
previousValue
.
getVersion
())
return
new
StoredModel
(
null
,
MessageConstants
.
STATUS_UPDATE_VERSION_MISMATCH
);
//status = true;
rocksDB
.
delete
(
key
.
getBytes
());
if
(
ConfigConstants
.
DEBUG
)
{
System
.
out
.
println
(
"Deleted object with key = "
+
key
);
}
}
}
catch
(
RocksDBException
e
)
{
e
.
printStackTrace
();
}
return
new
StoredModel
(
previousValue
,
MessageConstants
.
STATUS_OK
);
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/StorageModel.java
0 → 100644
View file @
f7053183
package
hpdos.lib
;
import
java.io.Serializable
;
import
java.util.zip.CRC32
;
import
java.util.zip.Checksum
;
public
class
StorageModel
implements
Serializable
{
private
int
version
;
private
int
dataSize
;
private
final
String
key
;
// key is immutable
private
long
crc
;
private
int
accessType
;
private
String
value
;
private
final
String
owner
;
// ownership is immutable
public
StorageModel
(
int
version
,
int
dataSize
,
String
key
,
int
accessType
,
String
owner
,
String
value
)
{
this
.
version
=
version
;
this
.
dataSize
=
dataSize
;
this
.
key
=
key
;
this
.
accessType
=
accessType
;
this
.
value
=
value
;
this
.
owner
=
owner
;
// calculate CRC32 based on the value field
byte
[]
bytes
=
value
.
getBytes
();
Checksum
checksum
=
new
CRC32
();
checksum
.
update
(
bytes
,
0
,
bytes
.
length
);
this
.
crc
=
checksum
.
getValue
();
}
public
StorageModel
createVersionUpdatedModel
()
{
int
updatedVersion
=
(
this
.
getVersion
()
+
1
)
%
Integer
.
MAX_VALUE
;
// version wraps around
return
new
StorageModel
(
updatedVersion
,
this
.
getDataSize
(),
this
.
getKey
(),
this
.
getAccessType
(),
this
.
getOwner
(),
this
.
getValue
());
}
public
int
getVersion
()
{
return
version
;
}
public
void
setVersion
(
int
version
)
{
this
.
version
=
version
;
}
public
int
getDataSize
()
{
return
dataSize
;
}
public
void
setDataSize
(
int
dataSize
)
{
this
.
dataSize
=
dataSize
;
}
public
String
getKey
()
{
return
key
;
}
public
long
getCrc
()
{
return
crc
;
}
public
void
setCrc
(
long
crc
)
{
this
.
crc
=
crc
;
}
public
int
getAccessType
()
{
return
accessType
;
}
public
void
setAccessType
(
int
accessType
)
{
this
.
accessType
=
accessType
;
}
public
String
getValue
()
{
return
value
;
}
public
void
setValue
(
String
value
)
{
this
.
value
=
value
;
}
public
String
getOwner
()
{
return
owner
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
null
)
return
false
;
if
(
obj
.
getClass
()
!=
this
.
getClass
())
return
false
;
StorageModel
model
=
(
StorageModel
)
obj
;
return
this
.
getVersion
()
==
model
.
getVersion
();
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/StorageService.java
0 → 100644
View file @
f7053183
package
hpdos.lib
;
public
interface
StorageService
{
StoredModel
create
(
String
key
,
StorageModel
value
);
StoredModel
readByKey
(
String
key
);
StoredModel
update
(
String
key
,
StorageModel
value
);
StoredModel
delete
(
String
key
,
StorageModel
version
);
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/lib/StoredModel.java
0 → 100644
View file @
f7053183
package
hpdos.lib
;
public
class
StoredModel
{
private
StorageModel
data
;
private
int
status
;
public
StoredModel
(
StorageModel
data
,
int
status
)
{
this
.
data
=
data
;
this
.
status
=
status
;
}
public
StorageModel
getData
()
{
return
data
;
}
public
void
setData
(
StorageModel
data
)
{
this
.
data
=
data
;
}
public
int
getStatus
()
{
return
status
;
}
public
void
setStatus
(
int
status
)
{
this
.
status
=
status
;
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/message/MessageConstants.java
0 → 100644
View file @
f7053183
package
hpdos.message
;
public
class
MessageConstants
{
public
static
final
int
INIT_VERSION
=
0
;
public
static
final
int
INVALID_VERSION
=
-
1
;
public
static
final
int
METADATA_ACCESS_PRIVATE
=
700
;
public
static
final
int
METADATA_ACCESS_SHARED
=
777
;
// 00 to 99 - Client Server Interaction operations
public
static
final
int
PACKET_METADATA_REQUEST
=
0
;
public
static
final
int
PACKET_METADATA_RESPONSE
=
1
;
// Distinguishing ACK and NACK packets
public
static
final
int
STATUS_OK
=
200
;
public
static
final
int
STATUS_UNAUTHORIZED_PRIVATE_KEY_ACCESS
=
401
;
public
static
final
int
STATUS_REPLICATION_FAILED
=
402
;
public
static
final
int
STATUS_SERVER_NOT_MASTER
=
403
;
public
static
final
int
STATUS_KEY_NOT_FOUND
=
404
;
public
static
final
int
STATUS_REPLICATION_TIMEOUT
=
405
;
public
static
final
int
STATUS_IO_WRITE_FAILED
=
406
;
public
static
final
int
STATUS_KEY_EXISTS
=
407
;
public
static
final
int
STATUS_UPDATE_VERSION_MISMATCH
=
408
;
// 100 to 199 - HPDOS System internal operations
public
static
final
int
MASTER_HEARTBEAT
=
100
;
public
static
final
int
METADATA_CREATE
=
101
;
public
static
final
int
METADATA_READ
=
102
;
public
static
final
int
METADATA_UPDATE
=
103
;
public
static
final
int
METADATA_DELETE
=
104
;
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/message/RequestBuilder.java
0 → 100644
View file @
f7053183
package
hpdos.message
;
import
hpdos.grpc.Packet
;
import
hpdos.grpc.ReplicationRequest
;
import
hpdos.grpc.Request
;
import
java.util.ArrayList
;
public
class
RequestBuilder
{
public
static
Request
buildRequest
(
int
operationType
,
int
version
,
int
dataSize
,
String
key
,
int
crc
,
String
value
)
{
Request
.
Builder
request
=
Request
.
newBuilder
();
request
.
setOperationType
(
operationType
);
request
.
setVersion
(
version
);
request
.
setDataSize
(
dataSize
);
request
.
setKey
(
key
);
request
.
setCrc
(
crc
);
request
.
setValue
(
value
);
return
request
.
build
();
}
public
static
Packet
buildPacket
(
ArrayList
<
Request
>
requests
)
{
Packet
.
Builder
packet
=
Packet
.
newBuilder
();
packet
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_REQUEST
);
packet
.
addAllRequest
(
requests
);
return
packet
.
build
();
}
public
static
ReplicationRequest
buildReplicationRequest
(
ArrayList
<
Request
>
requests
)
{
ReplicationRequest
.
Builder
builder
=
ReplicationRequest
.
newBuilder
();
builder
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_REQUEST
);
builder
.
addAllRequest
(
requests
);
return
builder
.
build
();
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/java/hpdos/message/ResponseBuilder.java
0 → 100644
View file @
f7053183
package
hpdos.message
;
import
hpdos.grpc.*
;
import
java.util.ArrayList
;
public
class
ResponseBuilder
{
public
static
Ack
buildAck
(
int
version
,
int
dataSize
,
String
key
,
long
crc
,
String
value
)
{
Ack
.
Builder
ack
=
Ack
.
newBuilder
();
ack
.
setKey
(
key
);
ack
.
setVersion
(
version
);
ack
.
setDataSize
(
dataSize
);
ack
.
setCrc
(
crc
);
ack
.
setValue
(
value
);
return
ack
.
build
();
}
public
static
Nack
buildNack
(
int
version
,
String
key
)
{
Nack
.
Builder
nack
=
Nack
.
newBuilder
();
nack
.
setKey
(
key
);
nack
.
setVersion
(
version
);
return
nack
.
build
();
}
public
static
Response
buildResponsePacket
(
int
operationType
,
int
status
,
Ack
ack
,
Nack
nack
)
{
Response
.
Builder
response
=
Response
.
newBuilder
();
response
.
setOperationType
(
operationType
);
response
.
setStatus
(
status
);
if
(
ack
!=
null
)
response
.
setAck
(
ack
);
else
response
.
clearAck
();
if
(
nack
!=
null
)
response
.
setNack
(
nack
);
else
response
.
clearNack
();
return
response
.
build
();
}
public
static
Packet
buildPacket
(
ArrayList
<
Response
>
responses
)
{
Packet
.
Builder
packet
=
Packet
.
newBuilder
();
packet
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_RESPONSE
);
packet
.
addAllResponse
(
responses
);
return
packet
.
build
();
}
public
static
Packet
buildPacket
(
Response
response
)
{
Packet
.
Builder
packet
=
Packet
.
newBuilder
();
packet
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_RESPONSE
);
packet
.
addResponse
(
response
);
return
packet
.
build
();
}
public
static
ReplicationResponse
buildReplicationResponse
(
Response
response
)
{
ReplicationResponse
.
Builder
packet
=
ReplicationResponse
.
newBuilder
();
packet
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_RESPONSE
);
packet
.
addResponse
(
response
);
return
packet
.
build
();
}
public
static
ReplicationResponse
buildReplicationResponse
(
ArrayList
<
Response
>
response
)
{
ReplicationResponse
.
Builder
packet
=
ReplicationResponse
.
newBuilder
();
packet
.
setPacketType
(
MessageConstants
.
PACKET_METADATA_RESPONSE
);
packet
.
addAllResponse
(
response
);
return
packet
.
build
();
}
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/proto/Heartbeat.proto
0 → 100644
View file @
f7053183
syntax
=
"proto3"
;
package
hpdos
.
grpc
;
option
java_multiple_files
=
true
;
option
java_package
=
"hpdos.grpc"
;
option
java_outer_classname
=
"Heartbeat"
;
service
HeartbeatService
{
/**
Exchange heartbeat
*/
rpc
heartbeat
(
HeartbeatRequest
)
returns
(
HeartbeatResponse
)
{}
}
message
HeartbeatRequest
{
int32
packetType
=
1
;
int32
operationType
=
2
;
string
ip
=
3
;
int32
port
=
4
;
string
followerID
=
5
;
}
message
HeartbeatResponse
{
int32
packetType
=
1
;
int32
operationType
=
2
;
bool
status
=
3
;
string
masterID
=
4
;
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/proto/PacketFormat.proto
0 → 100644
View file @
f7053183
syntax
=
"proto3"
;
package
hpdos
.
grpc
;
option
java_multiple_files
=
true
;
option
java_package
=
"hpdos.grpc"
;
option
java_outer_classname
=
"PacketFormatProto"
;
service
NetworkService
{
/**
Receive Packet from client
*/
rpc
readMetadata
(
Packet
)
returns
(
Packet
)
{}
rpc
createMetadata
(
Packet
)
returns
(
Packet
)
{}
rpc
updateMetadata
(
Packet
)
returns
(
Packet
)
{}
rpc
deleteMetadata
(
Packet
)
returns
(
Packet
)
{}
rpc
getReadReplicaList
(
RequestList
)
returns
(
ResponseList
)
{}
}
message
Packet
{
int32
packetType
=
1
;
repeated
Request
request
=
2
;
repeated
Response
response
=
3
;
}
message
Request
{
int32
operationType
=
1
;
int32
version
=
2
;
int32
dataSize
=
3
;
string
key
=
4
;
int64
crc
=
5
;
int32
accessType
=
6
;
string
clientID
=
7
;
string
value
=
8
;
}
message
Response
{
int32
operationType
=
1
;
int32
status
=
2
;
Ack
ack
=
3
;
Nack
nack
=
4
;
}
message
Ack
{
int32
version
=
2
;
int32
dataSize
=
3
;
string
key
=
4
;
int64
crc
=
5
;
string
value
=
6
;
}
message
Nack
{
string
key
=
2
;
int32
version
=
3
;
}
message
RequestList
{}
message
ResponseList
{
int32
operationType
=
1
;
int32
status
=
2
;
repeated
Follower
follower
=
3
;
}
message
Follower
{
string
ip
=
1
;
int32
port
=
2
;
string
followerID
=
3
;
int64
lastSeen
=
4
;
}
\ No newline at end of file
code/lsm-tree-impl/host-app/hpdos_server/app/src/main/proto/Replicate.proto
0 → 100644
View file @
f7053183
syntax
=
"proto3"
;
package
hpdos
.
grpc
;
import
"PacketFormat.proto"
;
option
java_multiple_files
=
true
;
option
java_package
=
"hpdos.grpc"
;
option
java_outer_classname
=
"Replicate"
;
service
ReplicationService
{
/**
Receive Packet from client
*/
rpc
replicateMetadata
(
ReplicationRequest
)
returns
(
ReplicationResponse
)
{}
}
message
ReplicationRequest
{
int32
packetType
=
1
;
repeated
Request
request
=
2
;
}
message
ReplicationResponse
{
int32
packetType
=
1
;
repeated
Response
response
=
2
;
}
code/lsm-tree-impl/host-app/hpdos_server/app/src/test/java/hpdos/AppTest.java
0 → 100644
View file @
f7053183
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package
hpdos
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
public
class
AppTest
{
@Test
public
void
testAppHasAGreeting
()
{
MetadataServer
classUnderTest
=
new
MetadataServer
();
assertNotNull
(
"app should have a greeting"
,
classUnderTest
.
getGreeting
());
}
}
code/lsm-tree-impl/host-app/hpdos_server/gradle/wrapper/gradle-wrapper.properties
0 → 100644
View file @
f7053183
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
code/lsm-tree-impl/host-app/hpdos_server/gradlew
0 → 100755
View file @
f7053183
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# 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
#
# https://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.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG
=
"
$0
"
# Need this for relative symlinks.
while
[
-h
"
$PRG
"
]
;
do
ls
=
`
ls
-ld
"
$PRG
"
`
link
=
`
expr
"
$ls
"
:
'.*-> \(.*\)$'
`
if
expr
"
$link
"
:
'/.*'
>
/dev/null
;
then
PRG
=
"
$link
"
else
PRG
=
`
dirname
"
$PRG
"
`
"/
$link
"
fi
done
SAVED
=
"
`
pwd
`
"
cd
"
`
dirname
\"
$PRG
\"
`
/"
>
/dev/null
APP_HOME
=
"
`
pwd
-P
`
"
cd
"
$SAVED
"
>
/dev/null
APP_NAME
=
"Gradle"
APP_BASE_NAME
=
`
basename
"
$0
"
`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS
=
'"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD
=
"maximum"
warn
()
{
echo
"
$*
"
}
die
()
{
echo
echo
"
$*
"
echo
exit
1
}
# OS specific support (must be 'true' or 'false').
cygwin
=
false
msys
=
false
darwin
=
false
nonstop
=
false
case
"
`
uname
`
"
in
CYGWIN
*
)
cygwin
=
true
;;
Darwin
*
)
darwin
=
true
;;
MINGW
*
)
msys
=
true
;;
NONSTOP
*
)
nonstop
=
true
;;
esac
CLASSPATH
=
$APP_HOME
/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if
[
-n
"
$JAVA_HOME
"
]
;
then
if
[
-x
"
$JAVA_HOME
/jre/sh/java"
]
;
then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD
=
"
$JAVA_HOME
/jre/sh/java"
else
JAVACMD
=
"
$JAVA_HOME
/bin/java"
fi
if
[
!
-x
"
$JAVACMD
"
]
;
then
die
"ERROR: JAVA_HOME is set to an invalid directory:
$JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD
=
"java"
which java
>
/dev/null 2>&1
||
die
"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if
[
"
$cygwin
"
=
"false"
-a
"
$darwin
"
=
"false"
-a
"
$nonstop
"
=
"false"
]
;
then
MAX_FD_LIMIT
=
`
ulimit
-H
-n
`
if
[
$?
-eq
0
]
;
then
if
[
"
$MAX_FD
"
=
"maximum"
-o
"
$MAX_FD
"
=
"max"
]
;
then
MAX_FD
=
"
$MAX_FD_LIMIT
"
fi
ulimit
-n
$MAX_FD
if
[
$?
-ne
0
]
;
then
warn
"Could not set maximum file descriptor limit:
$MAX_FD
"
fi
else
warn
"Could not query maximum file descriptor limit:
$MAX_FD_LIMIT
"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if
$darwin
;
then
GRADLE_OPTS
=
"
$GRADLE_OPTS
\"
-Xdock:name=
$APP_NAME
\"
\"
-Xdock:icon=
$APP_HOME
/media/gradle.icns
\"
"
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if
[
"
$cygwin
"
=
"true"
-o
"
$msys
"
=
"true"
]
;
then
APP_HOME
=
`
cygpath
--path
--mixed
"
$APP_HOME
"
`
CLASSPATH
=
`
cygpath
--path
--mixed
"
$CLASSPATH
"
`
JAVACMD
=
`
cygpath
--unix
"
$JAVACMD
"
`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW
=
`
find
-L
/
-maxdepth
1
-mindepth
1
-type
d 2>/dev/null
`
SEP
=
""
for
dir
in
$ROOTDIRSRAW
;
do
ROOTDIRS
=
"
$ROOTDIRS$SEP$dir
"
SEP
=
"|"
done
OURCYGPATTERN
=
"(^(
$ROOTDIRS
))"
# Add a user-defined pattern to the cygpath arguments
if
[
"
$GRADLE_CYGPATTERN
"
!=
""
]
;
then
OURCYGPATTERN
=
"
$OURCYGPATTERN
|(
$GRADLE_CYGPATTERN
)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i
=
0
for
arg
in
"
$@
"
;
do
CHECK
=
`
echo
"
$arg
"
|egrep
-c
"
$OURCYGPATTERN
"
-
`
CHECK2
=
`
echo
"
$arg
"
|egrep
-c
"^-"
`
### Determine if an option
if
[
$CHECK
-ne
0
]
&&
[
$CHECK2
-eq
0
]
;
then
### Added a condition
eval
`
echo
args
$i
`
=
`
cygpath
--path
--ignore
--mixed
"
$arg
"
`
else
eval
`
echo
args
$i
`
=
"
\"
$arg
\"
"
fi
i
=
`
expr
$i
+ 1
`
done
case
$i
in
0
)
set
--
;;
1
)
set
--
"
$args0
"
;;
2
)
set
--
"
$args0
"
"
$args1
"
;;
3
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
;;
4
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
;;
5
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
;;
6
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
;;
7
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
;;
8
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
"
$args7
"
;;
9
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
"
$args7
"
"
$args8
"
;;
esac
fi
# Escape application args
save
()
{
for
i
do
printf
%s
\\
n
"
$i
"
|
sed
"s/'/'
\\\\
''/g;1s/^/'/;
\$
s/
\$
/'
\\\\
/"
;
done
echo
" "
}
APP_ARGS
=
`
save
"
$@
"
`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set
--
$DEFAULT_JVM_OPTS
$JAVA_OPTS
$GRADLE_OPTS
"
\"
-Dorg.gradle.appname=
$APP_BASE_NAME
\"
"
-classpath
"
\"
$CLASSPATH
\"
"
org.gradle.wrapper.GradleWrapperMain
"
$APP_ARGS
"
exec
"
$JAVACMD
"
"
$@
"
code/lsm-tree-impl/host-app/hpdos_server/gradlew.bat
0 → 100644
View file @
f7053183
@rem
@rem
Copyright
2015
the
original
author
or
authors
.
@rem
@rem
Licensed
under
the
Apache
License
,
Version
2
.0
(
the
"License"
);
@rem
you
may
not
use
this
file
except
in
compliance
with
the
License
.
@rem
You
may
obtain
a
copy
of
the
License
at
@rem
@rem
https
://www.apache.org/licenses/LICENSE
-
2
.0
@rem
@rem
Unless
required
by
applicable
law
or
agreed
to
in
writing
,
software
@rem
distributed
under
the
License
is
distributed
on
an
"AS IS"
BASIS
,
@rem
WITHOUT
WARRANTIES
OR
CONDITIONS
OF
ANY
KIND
,
either
express
or
implied
.
@rem
See
the
License
for
the
specific
language
governing
permissions
and
@rem
limitations
under
the
License
.
@rem
@if
"
%DEBUG%
"
==
""
@echo
off
@rem ##########################################################################
@rem
@rem
Gradle
startup
script
for
Windows
@rem
@rem ##########################################################################
@rem
Set
local
scope
for
the
variables
with
windows
NT
shell
if
"
%OS%
"
==
"Windows_NT"
setlocal
set
DIRNAME
=
%~dp0
if
"
%DIRNAME%
"
==
""
set
DIRNAME
=
.
set
APP_BASE_NAME
=
%~n0
set
APP_HOME
=
%DIRNAME%
@rem
Resolve
any
"."
and
".."
in
APP_HOME
to
make
it
shorter
.
for
%%i
in
(
"
%APP_HOME%
"
)
do
set
APP_HOME
=
%%~fi
@rem
Add
default
JVM
options
here
.
You
can
also
use
JAVA_OPTS
and
GRADLE_OPTS
to
pass
JVM
options
to
this
script
.
set
DEFAULT_JVM_OPTS
=
"-Xmx64m"
"-Xms64m"
@rem
Find
java
.exe
if
defined
JAVA_HOME
goto
findJavaFromJavaHome
set
JAVA_EXE
=
java
.exe
%JAVA_EXE%
-version
>
NUL
2
>&
1
if
"
%ERRORLEVEL%
"
==
"0"
goto
execute
echo
.
echo
ERROR
:
JAVA_HOME
is
not
set
and
no
'java'
command
could
be
found
in
your
PATH
.
echo
.
echo
Please
set
the
JAVA_HOME
variable
in
your
environment
to
match
the
echo
location
of
your
Java
installation
.
goto
fail
:findJavaFromJavaHome
set
JAVA_HOME
=
%JAVA
_HOME:
"=
%
set JAVA_EXE=
%JAVA_HOME%
/bin/java.exe
if exist "
%JAVA_EXE%
" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory:
%JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
%APP_HOME%
\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"
%JAVA_EXE%
"
%DEFAULT_JVM_OPTS%
%JAVA_OPTS%
%GRADLE_OPTS%
"
-Dorg
.gradle.appname
=
%APP_BASE_NAME%
" -classpath "
%CLASSPATH%
" org.gradle.wrapper.GradleWrapperMain
%
*
:end
@rem End local scope for the variables with windows NT shell
if "
%ERRORLEVEL%
"=="
0
" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code
!
if not "" == "
%GRADLE_EXIT_CONSOLE%
" exit 1
exit /b 1
:mainEnd
if "
%OS%
"=="
Windows_NT
" endlocal
:omega
code/lsm-tree-impl/host-app/hpdos_server/settings.gradle
0 → 100644
View file @
f7053183
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/6.8.3/userguide/multi_project_builds.html
*/
rootProject
.
name
=
'hpdos'
include
(
'app'
)
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/Makefile
0 → 100644
View file @
f7053183
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation
# binary name
APP
=
l2fwd
# all source are stored in SRCS-y
SRCS-y
:=
main.c
# Build using pkg-config variables if possible
ifneq
($(shell pkg-config --exists libdpdk && echo 0),0)
$(error
"no installation of DPDK found"
)
endif
all
:
shared
.PHONY
:
shared static
shared
:
build/$(APP)-shared
ln
-sf
$(APP)
-shared
build/
$(APP)
static
:
build/$(APP)-static
ln
-sf
$(APP)
-static
build/
$(APP)
PKGCONF
?=
pkg-config
PC_FILE
:=
$(
shell
$(PKGCONF)
--path
libdpdk 2>/dev/null
)
CFLAGS
+=
-O3
$(
shell
$(PKGCONF)
--cflags
libdpdk
)
# Add flag to allow experimental API as l2fwd uses rte_ethdev_set_ptype API
CFLAGS
+=
-DALLOW_EXPERIMENTAL_API
LDFLAGS_SHARED
=
$(
shell
$(PKGCONF)
--libs
libdpdk
)
LDFLAGS_STATIC
=
$(
shell
$(PKGCONF)
--static
--libs
libdpdk
)
build/$(APP)-shared
:
$(SRCS-y) Makefile $(PC_FILE) | build
$(CC)
$(CFLAGS)
$
(
SRCS-y
)
-o
$@
$(LDFLAGS)
$(LDFLAGS_SHARED)
build/$(APP)-static
:
$(SRCS-y) Makefile $(PC_FILE) | build
$(CC)
$(CFLAGS)
$
(
SRCS-y
)
-o
$@
$(LDFLAGS)
$(LDFLAGS_STATIC)
build
:
@
mkdir
-p
$@
.PHONY
:
clean
clean
:
rm
-f
build/
$(APP)
build/
$(APP)
-static
build/
$(APP)
-shared
test
-d
build
&&
rmdir
-p
build
||
true
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/kv_str_main.c
0 → 100644
View file @
f7053183
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2016 Intel Corporation
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_string_fns.h>
#include <rte_udp.h>
#include <rte_ip.h>
#include <rte_hash.h>
#define CAPACITY 50000 // Size of the Hash Table
static
volatile
bool
force_quit
;
/* MAC updating enabled by default */
static
int
mac_updating
=
1
;
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 100
/* TX drain every ~100us */
#define MEMPOOL_CACHE_SIZE 256
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static
uint16_t
nb_rxd
=
RTE_TEST_RX_DESC_DEFAULT
;
static
uint16_t
nb_txd
=
RTE_TEST_TX_DESC_DEFAULT
;
/* ethernet addresses of ports */
static
struct
rte_ether_addr
l2fwd_ports_eth_addr
[
RTE_MAX_ETHPORTS
];
/* mask of enabled ports */
static
uint32_t
l2fwd_enabled_port_mask
=
0
;
/* list of enabled ports */
static
uint32_t
l2fwd_dst_ports
[
RTE_MAX_ETHPORTS
];
struct
port_pair_params
{
#define NUM_PORTS 2
uint16_t
port
[
NUM_PORTS
];
}
__rte_cache_aligned
;
static
struct
port_pair_params
port_pair_params_array
[
RTE_MAX_ETHPORTS
/
2
];
static
struct
port_pair_params
*
port_pair_params
;
static
uint16_t
nb_port_pair_params
;
static
unsigned
int
l2fwd_rx_queue_per_lcore
=
1
;
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_TX_QUEUE_PER_PORT 16
struct
lcore_queue_conf
{
unsigned
n_rx_port
;
unsigned
rx_port_list
[
MAX_RX_QUEUE_PER_LCORE
];
}
__rte_cache_aligned
;
struct
lcore_queue_conf
lcore_queue_conf
[
RTE_MAX_LCORE
];
static
struct
rte_eth_dev_tx_buffer
*
tx_buffer
[
RTE_MAX_ETHPORTS
];
static
struct
rte_eth_conf
port_conf
=
{
.
rxmode
=
{
.
split_hdr_size
=
0
,
},
.
txmode
=
{
.
mq_mode
=
ETH_MQ_TX_NONE
,
},
};
struct
rte_mempool
*
l2fwd_pktmbuf_pool
=
NULL
;
/* Per-port statistics struct */
struct
l2fwd_port_statistics
{
uint64_t
tx
;
uint64_t
rx
;
uint64_t
dropped
;
}
__rte_cache_aligned
;
struct
l2fwd_port_statistics
port_statistics
[
RTE_MAX_ETHPORTS
];
#define MAX_TIMER_PERIOD 86400
/* 1 day max */
/* A tsc-based timer responsible for triggering statistics printout */
static
uint64_t
timer_period
=
10
;
/* default period is 10 seconds */
struct
pkt_data
{
uint16_t
type
;
uint16_t
sep1
;
uint16_t
sep2
;
uint16_t
sep3
;
uint32_t
key
;
uint16_t
sep4
;
uint16_t
sep5
;
uint16_t
sep6
;
uint32_t
val
;
};
/* Print out statistics on packets dropped */
static
void
print_stats
(
void
)
{
uint64_t
total_packets_dropped
,
total_packets_tx
,
total_packets_rx
;
unsigned
portid
;
total_packets_dropped
=
0
;
total_packets_tx
=
0
;
total_packets_rx
=
0
;
const
char
clr
[]
=
{
27
,
'['
,
'2'
,
'J'
,
'\0'
};
const
char
topLeft
[]
=
{
27
,
'['
,
'1'
,
';'
,
'1'
,
'H'
,
'\0'
};
/* Clear screen and move to top left */
printf
(
"%s%s"
,
clr
,
topLeft
);
printf
(
"
\n
Port statistics ===================================="
);
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
{
/* skip disabled ports */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"
\n
Statistics for port %u ------------------------------"
"
\n
Packets sent: %24"
PRIu64
"
\n
Packets received: %20"
PRIu64
"
\n
Packets dropped: %21"
PRIu64
,
portid
,
port_statistics
[
portid
].
tx
,
port_statistics
[
portid
].
rx
,
port_statistics
[
portid
].
dropped
);
total_packets_dropped
+=
port_statistics
[
portid
].
dropped
;
total_packets_tx
+=
port_statistics
[
portid
].
tx
;
total_packets_rx
+=
port_statistics
[
portid
].
rx
;
}
printf
(
"
\n
Aggregate statistics ==============================="
"
\n
Total packets sent: %18"
PRIu64
"
\n
Total packets received: %14"
PRIu64
"
\n
Total packets dropped: %15"
PRIu64
,
total_packets_tx
,
total_packets_rx
,
total_packets_dropped
);
printf
(
"
\n
====================================================
\n
"
);
fflush
(
stdout
);
}
/*
* Create the hash table that will contain the flows that
* the node will handle, which will be used to decide if packet
* is transmitted or dropped.
*/
/*static struct rte_hash *
create_hash_table(const struct shared_info *info)
{
//uint32_t num_flows_node = info->num_flows / info->num_nodes;
//char name[RTE_HASH_NAMESIZE];
struct rte_hash *h;
// create table
struct rte_hash_parameters hash_params = {
.entries = 100000,
.key_len = sizeof(uint32_t), // Store IPv4 dest IP address
.socket_id = rte_socket_id(),
.hash_func_init_val = 0,
};
hash_params.name = "ht";
h = rte_hash_create(&hash_params);
if (h == NULL)
rte_exit(EXIT_FAILURE,
"Problem creating the hash table \n");
return h;
}
static void
populate_hash_table(const struct rte_hash *h, const struct shared_info *info)
{
unsigned int i;
int32_t ret;
uint32_t key;
// Add keys in table
for (i = 0; i < 100000; i++) {
key = rte_cpu_to_be_32(i);
ret = rte_hash_add_key(h, (void *) &key);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Unable to add entry %u "
"in hash table\n", i);
}
printf("Hash table: Adding keys\n");
}*/
unsigned
long
hash_function
(
char
*
str
)
{
unsigned
long
i
=
0
;
for
(
int
j
=
0
;
str
[
j
];
j
++
)
i
+=
str
[
j
];
return
i
%
CAPACITY
;
}
typedef
struct
Ht_item
Ht_item
;
// Define the Hash Table Item here
struct
Ht_item
{
char
*
key
;
char
*
value
;
};
typedef
struct
HashTable
HashTable
;
// Define the Hash Table here
struct
HashTable
{
// Contains an array of pointers
// to items
Ht_item
**
items
;
int
size
;
int
count
;
};
Ht_item
*
create_item
(
char
*
key
,
char
*
value
)
{
// Creates a pointer to a new hash table item
Ht_item
*
item
=
(
Ht_item
*
)
malloc
(
sizeof
(
Ht_item
));
item
->
key
=
(
char
*
)
malloc
(
strlen
(
key
)
+
1
);
item
->
value
=
(
char
*
)
malloc
(
strlen
(
value
)
+
1
);
strcpy
(
item
->
key
,
key
);
strcpy
(
item
->
value
,
value
);
return
item
;
}
HashTable
*
create_table
(
int
size
)
{
// Creates a new HashTable
HashTable
*
table
=
(
HashTable
*
)
malloc
(
sizeof
(
HashTable
));
table
->
size
=
size
;
table
->
count
=
0
;
table
->
items
=
(
Ht_item
**
)
calloc
(
table
->
size
,
sizeof
(
Ht_item
*
));
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
table
->
items
[
i
]
=
NULL
;
return
table
;
}
void
free_item
(
Ht_item
*
item
)
{
// Frees an item
free
(
item
->
key
);
free
(
item
->
value
);
free
(
item
);
}
void
free_table
(
HashTable
*
table
)
{
// Frees the table
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
{
Ht_item
*
item
=
table
->
items
[
i
];
if
(
item
!=
NULL
)
free_item
(
item
);
}
free
(
table
->
items
);
free
(
table
);
}
void
handle_collision
(
HashTable
*
table
,
unsigned
long
index
,
Ht_item
*
item
)
{
}
void
ht_insert
(
HashTable
*
table
,
char
*
key
,
char
*
value
)
{
// Create the item
Ht_item
*
item
=
create_item
(
key
,
value
);
// Compute the index
unsigned
long
index
=
hash_function
(
key
);
Ht_item
*
current_item
=
table
->
items
[
index
];
if
(
current_item
==
NULL
)
{
// Key does not exist.
if
(
table
->
count
==
table
->
size
)
{
// Hash Table Full
printf
(
"Insert Error: Hash Table is full
\n
"
);
// Remove the create item
free_item
(
item
);
return
;
}
// Insert directly
table
->
items
[
index
]
=
item
;
table
->
count
++
;
}
else
{
// Scenario 1: We only need to update value
if
(
strcmp
(
current_item
->
key
,
key
)
==
0
)
{
strcpy
(
table
->
items
[
index
]
->
value
,
value
);
return
;
}
else
{
// Scenario 2: Collision
// We will handle case this a bit later
handle_collision
(
table
,
index
,
item
);
return
;
}
}
}
char
*
ht_search
(
HashTable
*
table
,
char
*
key
)
{
// Searches the key in the hashtable
// and returns NULL if it doesn't exist
int
index
=
hash_function
(
key
);
Ht_item
*
item
=
table
->
items
[
index
];
// Ensure that we move to a non NULL item
if
(
item
!=
NULL
)
{
if
(
strcmp
(
item
->
key
,
key
)
==
0
)
return
item
->
value
;
}
return
NULL
;
}
void
print_search
(
HashTable
*
table
,
char
*
key
)
{
char
*
val
;
if
((
val
=
ht_search
(
table
,
key
))
==
NULL
)
{
printf
(
"Key:%s does not exist
\n
"
,
key
);
return
;
}
else
{
printf
(
"Key:%s, Value:%s
\n
"
,
key
,
val
);
}
}
void
print_table
(
HashTable
*
table
)
{
printf
(
"
\n
Hash Table
\n
-------------------
\n
"
);
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
{
if
(
table
->
items
[
i
])
{
printf
(
"Index:%d, Key:%s, Value:%s
\n
"
,
i
,
table
->
items
[
i
]
->
key
,
table
->
items
[
i
]
->
value
);
}
}
printf
(
"-------------------
\n\n
"
);
}
static
void
l2fwd_mac_updating
(
struct
rte_mbuf
*
m
,
unsigned
dest_portid
)
{
struct
rte_ether_hdr
*
eth
;
void
*
tmp
;
//struct pkt_data *data;
eth
=
rte_pktmbuf_mtod
(
m
,
struct
rte_ether_hdr
*
);
/* 02:00:00:00:00:xx */
/* 0c:42:a1:df:ac:40 41 */
tmp
=
&
eth
->
d_addr
.
addr_bytes
[
0
];
// @rinku
//*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);
*
((
uint64_t
*
)
tmp
)
=
0x40acdfa1420c
+
((
uint64_t
)
dest_portid
<<
56
);
/* src addr */
rte_ether_addr_copy
(
&
l2fwd_ports_eth_addr
[
dest_portid
],
&
eth
->
s_addr
);
// @rinku
struct
rte_ipv4_hdr
*
ipv4_hdr
;
if
(
RTE_ETH_IS_IPV4_HDR
(
m
->
packet_type
))
{
ipv4_hdr
=
rte_pktmbuf_mtod_offset
(
m
,
struct
rte_ipv4_hdr
*
,
sizeof
(
struct
rte_ether_hdr
));
uint32_t
tmp_dst
;
tmp_dst
=
ipv4_hdr
->
src_addr
;
ipv4_hdr
->
src_addr
=
ipv4_hdr
->
dst_addr
;
ipv4_hdr
->
dst_addr
=
tmp_dst
;
}
// @rinku
struct
rte_udp_hdr
*
udp
;
struct
pkt_data
*
data
;
if
(
ipv4_hdr
->
next_proto_id
==
IPPROTO_UDP
)
{
udp
=
(
struct
rte_udp_hdr
*
)((
unsigned
char
*
)
ipv4_hdr
+
sizeof
(
struct
rte_ipv4_hdr
));
uint16_t
port_dst
=
udp
->
dst_port
;
udp
->
dst_port
=
udp
->
src_port
;
udp
->
src_port
=
port_dst
;
//printf("len= %d ", ntohs(udp->dgram_len));
data
=
(
struct
pkt_data
*
)
((
unsigned
char
*
)
udp
+
sizeof
(
struct
rte_udp_hdr
));
if
((
data
!=
NULL
)
&&
(
ntohs
(
data
->
type
)
==
4
))
{
//if (data != NULL) {
//printf("len= %d ", udp->dgram_len);
//printf("%x %x %x %x %d %x %x %x %d \n",ntohs(data->type), ntohs(data->sep1), ntohs(data->sep2), ntohs(data->sep3), ntohl(data->key), ntohs(data->sep4), ntohs(data->sep5), ntohs(data->sep6),ntohl(data->val));
//printf("key= %d val= %d \n",ntohl(data->key),ntohs(data->val));
}
}
}
static
void
l2fwd_simple_forward
(
struct
rte_mbuf
*
m
,
unsigned
portid
)
{
unsigned
dst_port
;
int
sent
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
dst_port
=
l2fwd_dst_ports
[
portid
];
//printf("DEST PORT = %u", dst_port);
//@rinku
/*if (dst_port == 0)
dst_port = 1;
else if (dst_port == 1)
dst_port = 0;*/
if
(
mac_updating
)
l2fwd_mac_updating
(
m
,
dst_port
);
buffer
=
tx_buffer
[
dst_port
];
sent
=
rte_eth_tx_buffer
(
dst_port
,
0
,
buffer
,
m
);
if
(
sent
)
port_statistics
[
dst_port
].
tx
+=
sent
;
}
/* main processing loop */
static
void
l2fwd_main_loop
(
void
)
{
struct
rte_mbuf
*
pkts_burst
[
MAX_PKT_BURST
];
struct
rte_mbuf
*
m
;
int
sent
;
unsigned
lcore_id
;
uint64_t
prev_tsc
,
diff_tsc
,
cur_tsc
,
timer_tsc
;
unsigned
i
,
j
,
portid
,
nb_rx
;
struct
lcore_queue_conf
*
qconf
;
const
uint64_t
drain_tsc
=
(
rte_get_tsc_hz
()
+
US_PER_S
-
1
)
/
US_PER_S
*
BURST_TX_DRAIN_US
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
prev_tsc
=
0
;
timer_tsc
=
0
;
lcore_id
=
rte_lcore_id
();
qconf
=
&
lcore_queue_conf
[
lcore_id
];
if
(
qconf
->
n_rx_port
==
0
)
{
RTE_LOG
(
INFO
,
L2FWD
,
"lcore %u has nothing to do
\n
"
,
lcore_id
);
return
;
}
RTE_LOG
(
INFO
,
L2FWD
,
"entering main loop on lcore %u
\n
"
,
lcore_id
);
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
RTE_LOG
(
INFO
,
L2FWD
,
" -- lcoreid=%u portid=%u
\n
"
,
lcore_id
,
portid
);
}
HashTable
*
ht
=
create_table
(
CAPACITY
);
ht_insert
(
ht
,
"1"
,
"First address"
);
ht_insert
(
ht
,
"2"
,
"Second address"
);
print_search
(
ht
,
"1"
);
print_search
(
ht
,
"2"
);
print_search
(
ht
,
"3"
);
print_table
(
ht
);
free_table
(
ht
);
while
(
!
force_quit
)
{
cur_tsc
=
rte_rdtsc
();
/*
* TX burst queue drain
*/
diff_tsc
=
cur_tsc
-
prev_tsc
;
if
(
unlikely
(
diff_tsc
>
drain_tsc
))
{
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
l2fwd_dst_ports
[
qconf
->
rx_port_list
[
i
]];
buffer
=
tx_buffer
[
portid
];
sent
=
rte_eth_tx_buffer_flush
(
portid
,
0
,
buffer
);
if
(
sent
)
port_statistics
[
portid
].
tx
+=
sent
;
}
/* if timer is enabled */
if
(
timer_period
>
0
)
{
/* advance the timer */
timer_tsc
+=
diff_tsc
;
/* if timer has reached its timeout */
if
(
unlikely
(
timer_tsc
>=
timer_period
))
{
/* do this only on main core */
if
(
lcore_id
==
rte_get_main_lcore
())
{
print_stats
();
/* reset the timer */
timer_tsc
=
0
;
}
}
}
prev_tsc
=
cur_tsc
;
}
/*
* Read packet from RX queues
*/
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
nb_rx
=
rte_eth_rx_burst
(
portid
,
0
,
pkts_burst
,
MAX_PKT_BURST
);
port_statistics
[
portid
].
rx
+=
nb_rx
;
for
(
j
=
0
;
j
<
nb_rx
;
j
++
)
{
m
=
pkts_burst
[
j
];
rte_prefetch0
(
rte_pktmbuf_mtod
(
m
,
void
*
));
l2fwd_simple_forward
(
m
,
portid
);
}
}
}
}
static
int
l2fwd_launch_one_lcore
(
__rte_unused
void
*
dummy
)
{
l2fwd_main_loop
();
return
0
;
}
/* display usage */
static
void
l2fwd_usage
(
const
char
*
prgname
)
{
printf
(
"%s [EAL options] -- -p PORTMASK [-q NQ]
\n
"
" -p PORTMASK: hexadecimal bitmask of ports to configure
\n
"
" -q NQ: number of queue (=ports) per lcore (default is 1)
\n
"
" -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)
\n
"
" --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)
\n
"
" When enabled:
\n
"
" - The source MAC address is replaced by the TX port MAC address
\n
"
" - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID
\n
"
" --portmap: Configure forwarding port pair mapping
\n
"
" Default: alternate port pairs
\n\n
"
,
prgname
);
}
static
int
l2fwd_parse_portmask
(
const
char
*
portmask
)
{
char
*
end
=
NULL
;
unsigned
long
pm
;
/* parse hexadecimal string */
pm
=
strtoul
(
portmask
,
&
end
,
16
);
if
((
portmask
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
return
pm
;
}
static
int
l2fwd_parse_port_pair_config
(
const
char
*
q_arg
)
{
enum
fieldnames
{
FLD_PORT1
=
0
,
FLD_PORT2
,
_NUM_FLD
};
unsigned
long
int_fld
[
_NUM_FLD
];
const
char
*
p
,
*
p0
=
q_arg
;
char
*
str_fld
[
_NUM_FLD
];
unsigned
int
size
;
char
s
[
256
];
char
*
end
;
int
i
;
nb_port_pair_params
=
0
;
while
((
p
=
strchr
(
p0
,
'('
))
!=
NULL
)
{
++
p
;
p0
=
strchr
(
p
,
')'
);
if
(
p0
==
NULL
)
return
-
1
;
size
=
p0
-
p
;
if
(
size
>=
sizeof
(
s
))
return
-
1
;
memcpy
(
s
,
p
,
size
);
s
[
size
]
=
'\0'
;
if
(
rte_strsplit
(
s
,
sizeof
(
s
),
str_fld
,
_NUM_FLD
,
','
)
!=
_NUM_FLD
)
return
-
1
;
for
(
i
=
0
;
i
<
_NUM_FLD
;
i
++
)
{
errno
=
0
;
int_fld
[
i
]
=
strtoul
(
str_fld
[
i
],
&
end
,
0
);
if
(
errno
!=
0
||
end
==
str_fld
[
i
]
||
int_fld
[
i
]
>=
RTE_MAX_ETHPORTS
)
return
-
1
;
}
if
(
nb_port_pair_params
>=
RTE_MAX_ETHPORTS
/
2
)
{
printf
(
"exceeded max number of port pair params: %hu
\n
"
,
nb_port_pair_params
);
return
-
1
;
}
port_pair_params_array
[
nb_port_pair_params
].
port
[
0
]
=
(
uint16_t
)
int_fld
[
FLD_PORT1
];
port_pair_params_array
[
nb_port_pair_params
].
port
[
1
]
=
(
uint16_t
)
int_fld
[
FLD_PORT2
];
++
nb_port_pair_params
;
}
port_pair_params
=
port_pair_params_array
;
return
0
;
}
static
unsigned
int
l2fwd_parse_nqueue
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
unsigned
long
n
;
/* parse hexadecimal string */
n
=
strtoul
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
if
(
n
==
0
)
return
0
;
if
(
n
>=
MAX_RX_QUEUE_PER_LCORE
)
return
0
;
return
n
;
}
static
int
l2fwd_parse_timer_period
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
int
n
;
/* parse number string */
n
=
strtol
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
-
1
;
if
(
n
>=
MAX_TIMER_PERIOD
)
return
-
1
;
return
n
;
}
static
const
char
short_options
[]
=
"p:"
/* portmask */
"q:"
/* number of queues */
"T:"
/* timer period */
;
#define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
#define CMD_LINE_OPT_PORTMAP_CONFIG "portmap"
enum
{
/* long options mapped to a short option */
/* first long only option value must be >= 256, so that we won't
* conflict with short options */
CMD_LINE_OPT_MIN_NUM
=
256
,
CMD_LINE_OPT_PORTMAP_NUM
,
};
static
const
struct
option
lgopts
[]
=
{
{
CMD_LINE_OPT_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
1
},
{
CMD_LINE_OPT_NO_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
0
},
{
CMD_LINE_OPT_PORTMAP_CONFIG
,
1
,
0
,
CMD_LINE_OPT_PORTMAP_NUM
},
{
NULL
,
0
,
0
,
0
}
};
/* Parse the argument given in the command line of the application */
static
int
l2fwd_parse_args
(
int
argc
,
char
**
argv
)
{
int
opt
,
ret
,
timer_secs
;
char
**
argvopt
;
int
option_index
;
char
*
prgname
=
argv
[
0
];
argvopt
=
argv
;
port_pair_params
=
NULL
;
while
((
opt
=
getopt_long
(
argc
,
argvopt
,
short_options
,
lgopts
,
&
option_index
))
!=
EOF
)
{
switch
(
opt
)
{
/* portmask */
case
'p'
:
l2fwd_enabled_port_mask
=
l2fwd_parse_portmask
(
optarg
);
if
(
l2fwd_enabled_port_mask
==
0
)
{
printf
(
"invalid portmask
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* nqueue */
case
'q'
:
l2fwd_rx_queue_per_lcore
=
l2fwd_parse_nqueue
(
optarg
);
if
(
l2fwd_rx_queue_per_lcore
==
0
)
{
printf
(
"invalid queue number
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* timer period */
case
'T'
:
timer_secs
=
l2fwd_parse_timer_period
(
optarg
);
if
(
timer_secs
<
0
)
{
printf
(
"invalid timer period
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
timer_period
=
timer_secs
;
break
;
/* long options */
case
CMD_LINE_OPT_PORTMAP_NUM
:
ret
=
l2fwd_parse_port_pair_config
(
optarg
);
if
(
ret
)
{
fprintf
(
stderr
,
"Invalid config
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
default:
l2fwd_usage
(
prgname
);
return
-
1
;
}
}
if
(
optind
>=
0
)
argv
[
optind
-
1
]
=
prgname
;
ret
=
optind
-
1
;
optind
=
1
;
/* reset getopt lib */
return
ret
;
}
/*
* Check port pair config with enabled port mask,
* and for valid port pair combinations.
*/
static
int
check_port_pair_config
(
void
)
{
uint32_t
port_pair_config_mask
=
0
;
uint32_t
port_pair_mask
=
0
;
uint16_t
index
,
i
,
portid
;
for
(
index
=
0
;
index
<
nb_port_pair_params
;
index
++
)
{
port_pair_mask
=
0
;
for
(
i
=
0
;
i
<
NUM_PORTS
;
i
++
)
{
portid
=
port_pair_params
[
index
].
port
[
i
];
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"port %u is not enabled in port mask
\n
"
,
portid
);
return
-
1
;
}
if
(
!
rte_eth_dev_is_valid_port
(
portid
))
{
printf
(
"port %u is not present on the board
\n
"
,
portid
);
return
-
1
;
}
port_pair_mask
|=
1
<<
portid
;
}
if
(
port_pair_config_mask
&
port_pair_mask
)
{
printf
(
"port %u is used in other port pairs
\n
"
,
portid
);
return
-
1
;
}
port_pair_config_mask
|=
port_pair_mask
;
}
l2fwd_enabled_port_mask
&=
port_pair_config_mask
;
return
0
;
}
/* Check the link status of all ports in up to 9s, and print them finally */
static
void
check_all_ports_link_status
(
uint32_t
port_mask
)
{
#define CHECK_INTERVAL 100
/* 100ms */
#define MAX_CHECK_TIME 90
/* 9s (90 * 100ms) in total */
uint16_t
portid
;
uint8_t
count
,
all_ports_up
,
print_flag
=
0
;
struct
rte_eth_link
link
;
int
ret
;
char
link_status_text
[
RTE_ETH_LINK_MAX_STR_LEN
];
printf
(
"
\n
Checking link status"
);
fflush
(
stdout
);
for
(
count
=
0
;
count
<=
MAX_CHECK_TIME
;
count
++
)
{
if
(
force_quit
)
return
;
all_ports_up
=
1
;
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
(
force_quit
)
return
;
if
((
port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
memset
(
&
link
,
0
,
sizeof
(
link
));
ret
=
rte_eth_link_get_nowait
(
portid
,
&
link
);
if
(
ret
<
0
)
{
all_ports_up
=
0
;
if
(
print_flag
==
1
)
printf
(
"Port %u link get failed: %s
\n
"
,
portid
,
rte_strerror
(
-
ret
));
continue
;
}
/* print link status if flag set */
if
(
print_flag
==
1
)
{
rte_eth_link_to_str
(
link_status_text
,
sizeof
(
link_status_text
),
&
link
);
printf
(
"Port %d %s
\n
"
,
portid
,
link_status_text
);
continue
;
}
/* clear all_ports_up flag if any link down */
if
(
link
.
link_status
==
ETH_LINK_DOWN
)
{
all_ports_up
=
0
;
break
;
}
}
/* after finally printing all link status, get out */
if
(
print_flag
==
1
)
break
;
if
(
all_ports_up
==
0
)
{
printf
(
"."
);
fflush
(
stdout
);
rte_delay_ms
(
CHECK_INTERVAL
);
}
/* set the print_flag if all ports up or timeout */
if
(
all_ports_up
==
1
||
count
==
(
MAX_CHECK_TIME
-
1
))
{
print_flag
=
1
;
printf
(
"done
\n
"
);
}
}
}
static
void
signal_handler
(
int
signum
)
{
if
(
signum
==
SIGINT
||
signum
==
SIGTERM
)
{
printf
(
"
\n\n
Signal %d received, preparing to exit...
\n
"
,
signum
);
force_quit
=
true
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
struct
lcore_queue_conf
*
qconf
;
int
ret
;
uint16_t
nb_ports
;
uint16_t
nb_ports_available
=
0
;
uint16_t
portid
,
last_port
;
unsigned
lcore_id
,
rx_lcore_id
;
unsigned
nb_ports_in_mask
=
0
;
unsigned
int
nb_lcores
=
0
;
unsigned
int
nb_mbufs
;
/* init EAL */
ret
=
rte_eal_init
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid EAL arguments
\n
"
);
argc
-=
ret
;
argv
+=
ret
;
force_quit
=
false
;
signal
(
SIGINT
,
signal_handler
);
signal
(
SIGTERM
,
signal_handler
);
/* parse application arguments (after the EAL ones) */
ret
=
l2fwd_parse_args
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid L2FWD arguments
\n
"
);
printf
(
"MAC updating %s
\n
"
,
mac_updating
?
"enabled"
:
"disabled"
);
/* convert to number of cycles */
timer_period
*=
rte_get_timer_hz
();
nb_ports
=
rte_eth_dev_count_avail
();
if
(
nb_ports
==
0
)
rte_exit
(
EXIT_FAILURE
,
"No Ethernet ports - bye
\n
"
);
if
(
port_pair_params
!=
NULL
)
{
if
(
check_port_pair_config
()
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid port pair config
\n
"
);
}
/* check port mask to possible port mask */
if
(
l2fwd_enabled_port_mask
&
~
((
1
<<
nb_ports
)
-
1
))
rte_exit
(
EXIT_FAILURE
,
"Invalid portmask; possible (0x%x)
\n
"
,
(
1
<<
nb_ports
)
-
1
);
/* reset l2fwd_dst_ports */
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
l2fwd_dst_ports
[
portid
]
=
0
;
last_port
=
0
;
/* populate destination port details */
if
(
port_pair_params
!=
NULL
)
{
uint16_t
idx
,
p
;
for
(
idx
=
0
;
idx
<
(
nb_port_pair_params
<<
1
);
idx
++
)
{
p
=
idx
&
1
;
portid
=
port_pair_params
[
idx
>>
1
].
port
[
p
];
l2fwd_dst_ports
[
portid
]
=
port_pair_params
[
idx
>>
1
].
port
[
p
^
1
];
}
}
else
{
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
if
(
nb_ports_in_mask
%
2
)
{
l2fwd_dst_ports
[
portid
]
=
last_port
;
l2fwd_dst_ports
[
last_port
]
=
portid
;
}
else
{
last_port
=
portid
;
}
nb_ports_in_mask
++
;
}
if
(
nb_ports_in_mask
%
2
)
{
printf
(
"Notice: odd number of ports in portmask.
\n
"
);
l2fwd_dst_ports
[
last_port
]
=
last_port
;
}
}
rx_lcore_id
=
0
;
qconf
=
NULL
;
/* Initialize the port/queue configuration of each logical core */
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
/* get the lcore_id for this port */
while
(
rte_lcore_is_enabled
(
rx_lcore_id
)
==
0
||
lcore_queue_conf
[
rx_lcore_id
].
n_rx_port
==
l2fwd_rx_queue_per_lcore
)
{
rx_lcore_id
++
;
if
(
rx_lcore_id
>=
RTE_MAX_LCORE
)
rte_exit
(
EXIT_FAILURE
,
"Not enough cores
\n
"
);
}
if
(
qconf
!=
&
lcore_queue_conf
[
rx_lcore_id
])
{
/* Assigned a new logical core in the loop above. */
qconf
=
&
lcore_queue_conf
[
rx_lcore_id
];
nb_lcores
++
;
}
qconf
->
rx_port_list
[
qconf
->
n_rx_port
]
=
portid
;
qconf
->
n_rx_port
++
;
printf
(
"Lcore %u: RX port %u TX port %u
\n
"
,
rx_lcore_id
,
portid
,
l2fwd_dst_ports
[
portid
]);
}
nb_mbufs
=
RTE_MAX
(
nb_ports
*
(
nb_rxd
+
nb_txd
+
MAX_PKT_BURST
+
nb_lcores
*
MEMPOOL_CACHE_SIZE
),
8192U
);
/* create the mbuf pool */
l2fwd_pktmbuf_pool
=
rte_pktmbuf_pool_create
(
"mbuf_pool"
,
nb_mbufs
,
MEMPOOL_CACHE_SIZE
,
0
,
RTE_MBUF_DEFAULT_BUF_SIZE
,
rte_socket_id
());
if
(
l2fwd_pktmbuf_pool
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot init mbuf pool
\n
"
);
/* Initialise each port */
RTE_ETH_FOREACH_DEV
(
portid
)
{
struct
rte_eth_rxconf
rxq_conf
;
struct
rte_eth_txconf
txq_conf
;
struct
rte_eth_conf
local_port_conf
=
port_conf
;
struct
rte_eth_dev_info
dev_info
;
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"Skipping disabled port %u
\n
"
,
portid
);
continue
;
}
nb_ports_available
++
;
/* init port */
printf
(
"Initializing port %u... "
,
portid
);
fflush
(
stdout
);
ret
=
rte_eth_dev_info_get
(
portid
,
&
dev_info
);
if
(
ret
!=
0
)
rte_exit
(
EXIT_FAILURE
,
"Error during getting device (port %u) info: %s
\n
"
,
portid
,
strerror
(
-
ret
));
if
(
dev_info
.
tx_offload_capa
&
DEV_TX_OFFLOAD_MBUF_FAST_FREE
)
local_port_conf
.
txmode
.
offloads
|=
DEV_TX_OFFLOAD_MBUF_FAST_FREE
;
ret
=
rte_eth_dev_configure
(
portid
,
1
,
1
,
&
local_port_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot configure device: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_dev_adjust_nb_rx_tx_desc
(
portid
,
&
nb_rxd
,
&
nb_txd
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot adjust number of descriptors: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_macaddr_get
(
portid
,
&
l2fwd_ports_eth_addr
[
portid
]);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot get MAC address: err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one RX queue */
fflush
(
stdout
);
rxq_conf
=
dev_info
.
default_rxconf
;
rxq_conf
.
offloads
=
local_port_conf
.
rxmode
.
offloads
;
ret
=
rte_eth_rx_queue_setup
(
portid
,
0
,
nb_rxd
,
rte_eth_dev_socket_id
(
portid
),
&
rxq_conf
,
l2fwd_pktmbuf_pool
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_rx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one TX queue on each port */
fflush
(
stdout
);
txq_conf
=
dev_info
.
default_txconf
;
txq_conf
.
offloads
=
local_port_conf
.
txmode
.
offloads
;
ret
=
rte_eth_tx_queue_setup
(
portid
,
0
,
nb_txd
,
rte_eth_dev_socket_id
(
portid
),
&
txq_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_tx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* Initialize TX buffers */
tx_buffer
[
portid
]
=
rte_zmalloc_socket
(
"tx_buffer"
,
RTE_ETH_TX_BUFFER_SIZE
(
MAX_PKT_BURST
),
0
,
rte_eth_dev_socket_id
(
portid
));
if
(
tx_buffer
[
portid
]
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot allocate buffer for tx on port %u
\n
"
,
portid
);
rte_eth_tx_buffer_init
(
tx_buffer
[
portid
],
MAX_PKT_BURST
);
ret
=
rte_eth_tx_buffer_set_err_callback
(
tx_buffer
[
portid
],
rte_eth_tx_buffer_count_callback
,
&
port_statistics
[
portid
].
dropped
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot set error callback for tx buffer on port %u
\n
"
,
portid
);
ret
=
rte_eth_dev_set_ptypes
(
portid
,
RTE_PTYPE_UNKNOWN
,
NULL
,
0
);
if
(
ret
<
0
)
printf
(
"Port %u, Failed to disable Ptype parsing
\n
"
,
portid
);
/* Start device */
ret
=
rte_eth_dev_start
(
portid
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_dev_start:err=%d, port=%u
\n
"
,
ret
,
portid
);
printf
(
"done:
\n
"
);
ret
=
rte_eth_promiscuous_enable
(
portid
);
if
(
ret
!=
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_promiscuous_enable:err=%s, port=%u
\n
"
,
rte_strerror
(
-
ret
),
portid
);
printf
(
"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X
\n\n
"
,
portid
,
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
0
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
1
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
2
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
3
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
4
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
5
]);
/* initialize port stats */
memset
(
&
port_statistics
,
0
,
sizeof
(
port_statistics
));
}
if
(
!
nb_ports_available
)
{
rte_exit
(
EXIT_FAILURE
,
"All available ports are disabled. Please set portmask.
\n
"
);
}
check_all_ports_link_status
(
l2fwd_enabled_port_mask
);
ret
=
0
;
/* launch per-lcore init on every lcore */
rte_eal_mp_remote_launch
(
l2fwd_launch_one_lcore
,
NULL
,
CALL_MAIN
);
RTE_LCORE_FOREACH_WORKER
(
lcore_id
)
{
if
(
rte_eal_wait_lcore
(
lcore_id
)
<
0
)
{
ret
=
-
1
;
break
;
}
}
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"Closing port %d..."
,
portid
);
ret
=
rte_eth_dev_stop
(
portid
);
if
(
ret
!=
0
)
printf
(
"rte_eth_dev_stop: err=%d, port=%d
\n
"
,
ret
,
portid
);
rte_eth_dev_close
(
portid
);
printf
(
" Done
\n
"
);
}
printf
(
"Bye...
\n
"
);
return
ret
;
}
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/kv_wo_coll_main.c
0 → 100644
View file @
f7053183
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2016 Intel Corporation
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_string_fns.h>
#include <rte_udp.h>
#include <rte_ip.h>
#include <rte_hash.h>
#define CAPACITY 50000 // Size of the Hash Table
static
volatile
bool
force_quit
;
/* MAC updating enabled by default */
static
int
mac_updating
=
1
;
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 100
/* TX drain every ~100us */
#define MEMPOOL_CACHE_SIZE 256
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static
uint16_t
nb_rxd
=
RTE_TEST_RX_DESC_DEFAULT
;
static
uint16_t
nb_txd
=
RTE_TEST_TX_DESC_DEFAULT
;
/* ethernet addresses of ports */
static
struct
rte_ether_addr
l2fwd_ports_eth_addr
[
RTE_MAX_ETHPORTS
];
/* mask of enabled ports */
static
uint32_t
l2fwd_enabled_port_mask
=
0
;
/* list of enabled ports */
static
uint32_t
l2fwd_dst_ports
[
RTE_MAX_ETHPORTS
];
struct
port_pair_params
{
#define NUM_PORTS 2
uint16_t
port
[
NUM_PORTS
];
}
__rte_cache_aligned
;
static
struct
port_pair_params
port_pair_params_array
[
RTE_MAX_ETHPORTS
/
2
];
static
struct
port_pair_params
*
port_pair_params
;
static
uint16_t
nb_port_pair_params
;
static
unsigned
int
l2fwd_rx_queue_per_lcore
=
1
;
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_TX_QUEUE_PER_PORT 16
struct
lcore_queue_conf
{
unsigned
n_rx_port
;
unsigned
rx_port_list
[
MAX_RX_QUEUE_PER_LCORE
];
}
__rte_cache_aligned
;
struct
lcore_queue_conf
lcore_queue_conf
[
RTE_MAX_LCORE
];
static
struct
rte_eth_dev_tx_buffer
*
tx_buffer
[
RTE_MAX_ETHPORTS
];
static
struct
rte_eth_conf
port_conf
=
{
.
rxmode
=
{
.
split_hdr_size
=
0
,
},
.
txmode
=
{
.
mq_mode
=
ETH_MQ_TX_NONE
,
},
};
struct
rte_mempool
*
l2fwd_pktmbuf_pool
=
NULL
;
/* Per-port statistics struct */
struct
l2fwd_port_statistics
{
uint64_t
tx
;
uint64_t
rx
;
uint64_t
dropped
;
}
__rte_cache_aligned
;
struct
l2fwd_port_statistics
port_statistics
[
RTE_MAX_ETHPORTS
];
#define MAX_TIMER_PERIOD 86400
/* 1 day max */
/* A tsc-based timer responsible for triggering statistics printout */
static
uint64_t
timer_period
=
10
;
/* default period is 10 seconds */
struct
pkt_data
{
uint16_t
type
;
uint16_t
sep1
;
uint16_t
sep2
;
uint16_t
sep3
;
uint32_t
key
;
uint16_t
sep4
;
uint16_t
sep5
;
uint16_t
sep6
;
uint32_t
val
;
};
struct
HashTable
*
ht
;
/* Print out statistics on packets dropped */
static
void
print_stats
(
void
)
{
uint64_t
total_packets_dropped
,
total_packets_tx
,
total_packets_rx
;
unsigned
portid
;
total_packets_dropped
=
0
;
total_packets_tx
=
0
;
total_packets_rx
=
0
;
const
char
clr
[]
=
{
27
,
'['
,
'2'
,
'J'
,
'\0'
};
const
char
topLeft
[]
=
{
27
,
'['
,
'1'
,
';'
,
'1'
,
'H'
,
'\0'
};
/* Clear screen and move to top left */
printf
(
"%s%s"
,
clr
,
topLeft
);
printf
(
"
\n
Port statistics ===================================="
);
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
{
/* skip disabled ports */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"
\n
Statistics for port %u ------------------------------"
"
\n
Packets sent: %24"
PRIu64
"
\n
Packets received: %20"
PRIu64
"
\n
Packets dropped: %21"
PRIu64
,
portid
,
port_statistics
[
portid
].
tx
,
port_statistics
[
portid
].
rx
,
port_statistics
[
portid
].
dropped
);
total_packets_dropped
+=
port_statistics
[
portid
].
dropped
;
total_packets_tx
+=
port_statistics
[
portid
].
tx
;
total_packets_rx
+=
port_statistics
[
portid
].
rx
;
}
printf
(
"
\n
Aggregate statistics ==============================="
"
\n
Total packets sent: %18"
PRIu64
"
\n
Total packets received: %14"
PRIu64
"
\n
Total packets dropped: %15"
PRIu64
,
total_packets_tx
,
total_packets_rx
,
total_packets_dropped
);
printf
(
"
\n
====================================================
\n
"
);
fflush
(
stdout
);
}
/*
* Create the hash table that will contain the flows that
* the node will handle, which will be used to decide if packet
* is transmitted or dropped.
*/
/*static struct rte_hash *
create_hash_table(const struct shared_info *info)
{
//uint32_t num_flows_node = info->num_flows / info->num_nodes;
//char name[RTE_HASH_NAMESIZE];
struct rte_hash *h;
// create table
struct rte_hash_parameters hash_params = {
.entries = 100000,
.key_len = sizeof(uint32_t), // Store IPv4 dest IP address
.socket_id = rte_socket_id(),
.hash_func_init_val = 0,
};
hash_params.name = "ht";
h = rte_hash_create(&hash_params);
if (h == NULL)
rte_exit(EXIT_FAILURE,
"Problem creating the hash table \n");
return h;
}
static void
populate_hash_table(const struct rte_hash *h, const struct shared_info *info)
{
unsigned int i;
int32_t ret;
uint32_t key;
// Add keys in table
for (i = 0; i < 100000; i++) {
key = rte_cpu_to_be_32(i);
ret = rte_hash_add_key(h, (void *) &key);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Unable to add entry %u "
"in hash table\n", i);
}
printf("Hash table: Adding keys\n");
}*/
unsigned
long
hash_function
(
char
*
str
)
{
unsigned
long
i
=
0
;
for
(
int
j
=
0
;
str
[
j
];
j
++
)
i
+=
str
[
j
];
return
i
%
CAPACITY
;
}
typedef
struct
Ht_item
Ht_item
;
// Define the Hash Table Item here
struct
Ht_item
{
char
*
key
;
char
*
value
;
};
typedef
struct
HashTable
HashTable
;
// Define the Hash Table here
struct
HashTable
{
// Contains an array of pointers
// to items
Ht_item
**
items
;
int
size
;
int
count
;
};
Ht_item
*
create_item
(
char
*
key
,
char
*
value
)
{
// Creates a pointer to a new hash table item
Ht_item
*
item
=
(
Ht_item
*
)
malloc
(
sizeof
(
Ht_item
));
item
->
key
=
(
char
*
)
malloc
(
strlen
(
key
)
+
1
);
item
->
value
=
(
char
*
)
malloc
(
strlen
(
value
)
+
1
);
strcpy
(
item
->
key
,
key
);
strcpy
(
item
->
value
,
value
);
return
item
;
}
HashTable
*
create_table
(
int
size
)
{
// Creates a new HashTable
HashTable
*
table
=
(
HashTable
*
)
malloc
(
sizeof
(
HashTable
));
table
->
size
=
size
;
table
->
count
=
0
;
table
->
items
=
(
Ht_item
**
)
calloc
(
table
->
size
,
sizeof
(
Ht_item
*
));
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
table
->
items
[
i
]
=
NULL
;
return
table
;
}
void
free_item
(
Ht_item
*
item
)
{
// Frees an item
free
(
item
->
key
);
free
(
item
->
value
);
free
(
item
);
}
void
free_table
(
HashTable
*
table
)
{
// Frees the table
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
{
Ht_item
*
item
=
table
->
items
[
i
];
if
(
item
!=
NULL
)
free_item
(
item
);
}
free
(
table
->
items
);
free
(
table
);
}
void
handle_collision
(
HashTable
*
table
,
unsigned
long
index
,
Ht_item
*
item
)
{
}
void
ht_insert
(
HashTable
*
table
,
char
*
key
,
char
*
value
)
{
// Create the item
Ht_item
*
item
=
create_item
(
key
,
value
);
// Compute the index
unsigned
long
index
=
hash_function
(
key
);
Ht_item
*
current_item
=
table
->
items
[
index
];
if
(
current_item
==
NULL
)
{
// Key does not exist.
if
(
table
->
count
==
table
->
size
)
{
// Hash Table Full
printf
(
"Insert Error: Hash Table is full
\n
"
);
// Remove the create item
free_item
(
item
);
return
;
}
// Insert directly
table
->
items
[
index
]
=
item
;
table
->
count
++
;
}
else
{
// Scenario 1: We only need to update value
if
(
strcmp
(
current_item
->
key
,
key
)
==
0
)
{
strcpy
(
table
->
items
[
index
]
->
value
,
value
);
return
;
}
else
{
// Scenario 2: Collision
// We will handle case this a bit later
handle_collision
(
table
,
index
,
item
);
return
;
}
}
}
char
*
ht_search
(
HashTable
*
table
,
char
*
key
)
{
// Searches the key in the hashtable
// and returns NULL if it doesn't exist
int
index
=
hash_function
(
key
);
Ht_item
*
item
=
table
->
items
[
index
];
// Ensure that we move to a non NULL item
if
(
item
!=
NULL
)
{
if
(
strcmp
(
item
->
key
,
key
)
==
0
)
return
item
->
value
;
}
return
NULL
;
}
void
print_search
(
HashTable
*
table
,
char
*
key
)
{
char
*
val
;
if
((
val
=
ht_search
(
table
,
key
))
==
NULL
)
{
printf
(
"Key:%s does not exist
\n
"
,
key
);
return
;
}
else
{
printf
(
"Key:%s, Value:%s
\n
"
,
key
,
val
);
}
}
void
print_table
(
HashTable
*
table
)
{
printf
(
"
\n
Hash Table
\n
-------------------
\n
"
);
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
{
if
(
table
->
items
[
i
])
{
printf
(
"Index:%d, Key:%s, Value:%s
\n
"
,
i
,
table
->
items
[
i
]
->
key
,
table
->
items
[
i
]
->
value
);
}
}
printf
(
"-------------------
\n\n
"
);
}
static
void
l2fwd_mac_updating
(
struct
rte_mbuf
*
m
,
unsigned
dest_portid
)
{
struct
rte_ether_hdr
*
eth
;
void
*
tmp
;
//struct pkt_data *data;
eth
=
rte_pktmbuf_mtod
(
m
,
struct
rte_ether_hdr
*
);
/* 02:00:00:00:00:xx */
/* 0c:42:a1:df:ac:40 41 */
tmp
=
&
eth
->
d_addr
.
addr_bytes
[
0
];
// @rinku
//*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);
*
((
uint64_t
*
)
tmp
)
=
0x40acdfa1420c
+
((
uint64_t
)
dest_portid
<<
56
);
/* src addr */
rte_ether_addr_copy
(
&
l2fwd_ports_eth_addr
[
dest_portid
],
&
eth
->
s_addr
);
// @rinku
struct
rte_ipv4_hdr
*
ipv4_hdr
;
if
(
RTE_ETH_IS_IPV4_HDR
(
m
->
packet_type
))
{
ipv4_hdr
=
rte_pktmbuf_mtod_offset
(
m
,
struct
rte_ipv4_hdr
*
,
sizeof
(
struct
rte_ether_hdr
));
uint32_t
tmp_dst
;
tmp_dst
=
ipv4_hdr
->
src_addr
;
ipv4_hdr
->
src_addr
=
ipv4_hdr
->
dst_addr
;
ipv4_hdr
->
dst_addr
=
tmp_dst
;
}
// @rinku
struct
rte_udp_hdr
*
udp
;
struct
pkt_data
*
data
;
if
(
ipv4_hdr
->
next_proto_id
==
IPPROTO_UDP
)
{
udp
=
(
struct
rte_udp_hdr
*
)((
unsigned
char
*
)
ipv4_hdr
+
sizeof
(
struct
rte_ipv4_hdr
));
uint16_t
port_dst
=
udp
->
dst_port
;
udp
->
dst_port
=
udp
->
src_port
;
udp
->
src_port
=
port_dst
;
//printf("len= %d ", ntohs(udp->dgram_len));
data
=
(
struct
pkt_data
*
)
((
unsigned
char
*
)
udp
+
sizeof
(
struct
rte_udp_hdr
));
if
((
data
!=
NULL
)
&&
(
ntohs
(
data
->
type
)
==
4
))
{
//if (data != NULL) {
//printf("len= %d ", udp->dgram_len);
//printf("%x %x %x %x %d %x %x %x %d \n",ntohs(data->type), ntohs(data->sep1), ntohs(data->sep2), ntohs(data->sep3), ntohl(data->key), ntohs(data->sep4), ntohs(data->sep5), ntohs(data->sep6),ntohl(data->val));
//printf("key= %d val= %d \n",ntohl(data->key),ntohs(data->val));
char
k
[
6
];
sprintf
(
k
,
"%d"
,
ntohl
(
data
->
key
));
print_search
(
ht
,
k
);
}
}
}
static
void
l2fwd_simple_forward
(
struct
rte_mbuf
*
m
,
unsigned
portid
)
{
unsigned
dst_port
;
int
sent
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
dst_port
=
l2fwd_dst_ports
[
portid
];
//printf("DEST PORT = %u", dst_port);
//@rinku
/*if (dst_port == 0)
dst_port = 1;
else if (dst_port == 1)
dst_port = 0;*/
if
(
mac_updating
)
l2fwd_mac_updating
(
m
,
dst_port
);
buffer
=
tx_buffer
[
dst_port
];
sent
=
rte_eth_tx_buffer
(
dst_port
,
0
,
buffer
,
m
);
if
(
sent
)
port_statistics
[
dst_port
].
tx
+=
sent
;
}
/* main processing loop */
static
void
l2fwd_main_loop
(
void
)
{
struct
rte_mbuf
*
pkts_burst
[
MAX_PKT_BURST
];
struct
rte_mbuf
*
m
;
int
sent
;
unsigned
lcore_id
;
uint64_t
prev_tsc
,
diff_tsc
,
cur_tsc
,
timer_tsc
;
unsigned
i
,
j
,
portid
,
nb_rx
;
struct
lcore_queue_conf
*
qconf
;
const
uint64_t
drain_tsc
=
(
rte_get_tsc_hz
()
+
US_PER_S
-
1
)
/
US_PER_S
*
BURST_TX_DRAIN_US
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
prev_tsc
=
0
;
timer_tsc
=
0
;
lcore_id
=
rte_lcore_id
();
qconf
=
&
lcore_queue_conf
[
lcore_id
];
if
(
qconf
->
n_rx_port
==
0
)
{
RTE_LOG
(
INFO
,
L2FWD
,
"lcore %u has nothing to do
\n
"
,
lcore_id
);
return
;
}
RTE_LOG
(
INFO
,
L2FWD
,
"entering main loop on lcore %u
\n
"
,
lcore_id
);
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
RTE_LOG
(
INFO
,
L2FWD
,
" -- lcoreid=%u portid=%u
\n
"
,
lcore_id
,
portid
);
}
ht
=
create_table
(
CAPACITY
);
for
(
int
i
=
0
;
i
<
CAPACITY
;
i
++
){
char
k
[
6
],
v
[
6
];
int
val
=
i
+
1
;
sprintf
(
k
,
"%d"
,
i
);
sprintf
(
v
,
"%d"
,
val
);
ht_insert
(
ht
,
k
,
v
);
}
print_search
(
ht
,
"1234"
);
/*print_search(ht, "1");
print_search(ht, "2");
print_search(ht, "3");
print_table(ht);
free_table(ht);*/
while
(
!
force_quit
)
{
cur_tsc
=
rte_rdtsc
();
/*
* TX burst queue drain
*/
diff_tsc
=
cur_tsc
-
prev_tsc
;
if
(
unlikely
(
diff_tsc
>
drain_tsc
))
{
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
l2fwd_dst_ports
[
qconf
->
rx_port_list
[
i
]];
buffer
=
tx_buffer
[
portid
];
sent
=
rte_eth_tx_buffer_flush
(
portid
,
0
,
buffer
);
if
(
sent
)
port_statistics
[
portid
].
tx
+=
sent
;
}
/* if timer is enabled */
if
(
timer_period
>
0
)
{
/* advance the timer */
timer_tsc
+=
diff_tsc
;
/* if timer has reached its timeout */
if
(
unlikely
(
timer_tsc
>=
timer_period
))
{
/* do this only on main core */
if
(
lcore_id
==
rte_get_main_lcore
())
{
print_stats
();
/* reset the timer */
timer_tsc
=
0
;
}
}
}
prev_tsc
=
cur_tsc
;
}
/*
* Read packet from RX queues
*/
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
nb_rx
=
rte_eth_rx_burst
(
portid
,
0
,
pkts_burst
,
MAX_PKT_BURST
);
port_statistics
[
portid
].
rx
+=
nb_rx
;
for
(
j
=
0
;
j
<
nb_rx
;
j
++
)
{
m
=
pkts_burst
[
j
];
rte_prefetch0
(
rte_pktmbuf_mtod
(
m
,
void
*
));
l2fwd_simple_forward
(
m
,
portid
);
}
}
}
}
static
int
l2fwd_launch_one_lcore
(
__rte_unused
void
*
dummy
)
{
l2fwd_main_loop
();
return
0
;
}
/* display usage */
static
void
l2fwd_usage
(
const
char
*
prgname
)
{
printf
(
"%s [EAL options] -- -p PORTMASK [-q NQ]
\n
"
" -p PORTMASK: hexadecimal bitmask of ports to configure
\n
"
" -q NQ: number of queue (=ports) per lcore (default is 1)
\n
"
" -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)
\n
"
" --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)
\n
"
" When enabled:
\n
"
" - The source MAC address is replaced by the TX port MAC address
\n
"
" - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID
\n
"
" --portmap: Configure forwarding port pair mapping
\n
"
" Default: alternate port pairs
\n\n
"
,
prgname
);
}
static
int
l2fwd_parse_portmask
(
const
char
*
portmask
)
{
char
*
end
=
NULL
;
unsigned
long
pm
;
/* parse hexadecimal string */
pm
=
strtoul
(
portmask
,
&
end
,
16
);
if
((
portmask
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
return
pm
;
}
static
int
l2fwd_parse_port_pair_config
(
const
char
*
q_arg
)
{
enum
fieldnames
{
FLD_PORT1
=
0
,
FLD_PORT2
,
_NUM_FLD
};
unsigned
long
int_fld
[
_NUM_FLD
];
const
char
*
p
,
*
p0
=
q_arg
;
char
*
str_fld
[
_NUM_FLD
];
unsigned
int
size
;
char
s
[
256
];
char
*
end
;
int
i
;
nb_port_pair_params
=
0
;
while
((
p
=
strchr
(
p0
,
'('
))
!=
NULL
)
{
++
p
;
p0
=
strchr
(
p
,
')'
);
if
(
p0
==
NULL
)
return
-
1
;
size
=
p0
-
p
;
if
(
size
>=
sizeof
(
s
))
return
-
1
;
memcpy
(
s
,
p
,
size
);
s
[
size
]
=
'\0'
;
if
(
rte_strsplit
(
s
,
sizeof
(
s
),
str_fld
,
_NUM_FLD
,
','
)
!=
_NUM_FLD
)
return
-
1
;
for
(
i
=
0
;
i
<
_NUM_FLD
;
i
++
)
{
errno
=
0
;
int_fld
[
i
]
=
strtoul
(
str_fld
[
i
],
&
end
,
0
);
if
(
errno
!=
0
||
end
==
str_fld
[
i
]
||
int_fld
[
i
]
>=
RTE_MAX_ETHPORTS
)
return
-
1
;
}
if
(
nb_port_pair_params
>=
RTE_MAX_ETHPORTS
/
2
)
{
printf
(
"exceeded max number of port pair params: %hu
\n
"
,
nb_port_pair_params
);
return
-
1
;
}
port_pair_params_array
[
nb_port_pair_params
].
port
[
0
]
=
(
uint16_t
)
int_fld
[
FLD_PORT1
];
port_pair_params_array
[
nb_port_pair_params
].
port
[
1
]
=
(
uint16_t
)
int_fld
[
FLD_PORT2
];
++
nb_port_pair_params
;
}
port_pair_params
=
port_pair_params_array
;
return
0
;
}
static
unsigned
int
l2fwd_parse_nqueue
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
unsigned
long
n
;
/* parse hexadecimal string */
n
=
strtoul
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
if
(
n
==
0
)
return
0
;
if
(
n
>=
MAX_RX_QUEUE_PER_LCORE
)
return
0
;
return
n
;
}
static
int
l2fwd_parse_timer_period
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
int
n
;
/* parse number string */
n
=
strtol
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
-
1
;
if
(
n
>=
MAX_TIMER_PERIOD
)
return
-
1
;
return
n
;
}
static
const
char
short_options
[]
=
"p:"
/* portmask */
"q:"
/* number of queues */
"T:"
/* timer period */
;
#define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
#define CMD_LINE_OPT_PORTMAP_CONFIG "portmap"
enum
{
/* long options mapped to a short option */
/* first long only option value must be >= 256, so that we won't
* conflict with short options */
CMD_LINE_OPT_MIN_NUM
=
256
,
CMD_LINE_OPT_PORTMAP_NUM
,
};
static
const
struct
option
lgopts
[]
=
{
{
CMD_LINE_OPT_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
1
},
{
CMD_LINE_OPT_NO_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
0
},
{
CMD_LINE_OPT_PORTMAP_CONFIG
,
1
,
0
,
CMD_LINE_OPT_PORTMAP_NUM
},
{
NULL
,
0
,
0
,
0
}
};
/* Parse the argument given in the command line of the application */
static
int
l2fwd_parse_args
(
int
argc
,
char
**
argv
)
{
int
opt
,
ret
,
timer_secs
;
char
**
argvopt
;
int
option_index
;
char
*
prgname
=
argv
[
0
];
argvopt
=
argv
;
port_pair_params
=
NULL
;
while
((
opt
=
getopt_long
(
argc
,
argvopt
,
short_options
,
lgopts
,
&
option_index
))
!=
EOF
)
{
switch
(
opt
)
{
/* portmask */
case
'p'
:
l2fwd_enabled_port_mask
=
l2fwd_parse_portmask
(
optarg
);
if
(
l2fwd_enabled_port_mask
==
0
)
{
printf
(
"invalid portmask
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* nqueue */
case
'q'
:
l2fwd_rx_queue_per_lcore
=
l2fwd_parse_nqueue
(
optarg
);
if
(
l2fwd_rx_queue_per_lcore
==
0
)
{
printf
(
"invalid queue number
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* timer period */
case
'T'
:
timer_secs
=
l2fwd_parse_timer_period
(
optarg
);
if
(
timer_secs
<
0
)
{
printf
(
"invalid timer period
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
timer_period
=
timer_secs
;
break
;
/* long options */
case
CMD_LINE_OPT_PORTMAP_NUM
:
ret
=
l2fwd_parse_port_pair_config
(
optarg
);
if
(
ret
)
{
fprintf
(
stderr
,
"Invalid config
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
default:
l2fwd_usage
(
prgname
);
return
-
1
;
}
}
if
(
optind
>=
0
)
argv
[
optind
-
1
]
=
prgname
;
ret
=
optind
-
1
;
optind
=
1
;
/* reset getopt lib */
return
ret
;
}
/*
* Check port pair config with enabled port mask,
* and for valid port pair combinations.
*/
static
int
check_port_pair_config
(
void
)
{
uint32_t
port_pair_config_mask
=
0
;
uint32_t
port_pair_mask
=
0
;
uint16_t
index
,
i
,
portid
;
for
(
index
=
0
;
index
<
nb_port_pair_params
;
index
++
)
{
port_pair_mask
=
0
;
for
(
i
=
0
;
i
<
NUM_PORTS
;
i
++
)
{
portid
=
port_pair_params
[
index
].
port
[
i
];
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"port %u is not enabled in port mask
\n
"
,
portid
);
return
-
1
;
}
if
(
!
rte_eth_dev_is_valid_port
(
portid
))
{
printf
(
"port %u is not present on the board
\n
"
,
portid
);
return
-
1
;
}
port_pair_mask
|=
1
<<
portid
;
}
if
(
port_pair_config_mask
&
port_pair_mask
)
{
printf
(
"port %u is used in other port pairs
\n
"
,
portid
);
return
-
1
;
}
port_pair_config_mask
|=
port_pair_mask
;
}
l2fwd_enabled_port_mask
&=
port_pair_config_mask
;
return
0
;
}
/* Check the link status of all ports in up to 9s, and print them finally */
static
void
check_all_ports_link_status
(
uint32_t
port_mask
)
{
#define CHECK_INTERVAL 100
/* 100ms */
#define MAX_CHECK_TIME 90
/* 9s (90 * 100ms) in total */
uint16_t
portid
;
uint8_t
count
,
all_ports_up
,
print_flag
=
0
;
struct
rte_eth_link
link
;
int
ret
;
char
link_status_text
[
RTE_ETH_LINK_MAX_STR_LEN
];
printf
(
"
\n
Checking link status"
);
fflush
(
stdout
);
for
(
count
=
0
;
count
<=
MAX_CHECK_TIME
;
count
++
)
{
if
(
force_quit
)
return
;
all_ports_up
=
1
;
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
(
force_quit
)
return
;
if
((
port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
memset
(
&
link
,
0
,
sizeof
(
link
));
ret
=
rte_eth_link_get_nowait
(
portid
,
&
link
);
if
(
ret
<
0
)
{
all_ports_up
=
0
;
if
(
print_flag
==
1
)
printf
(
"Port %u link get failed: %s
\n
"
,
portid
,
rte_strerror
(
-
ret
));
continue
;
}
/* print link status if flag set */
if
(
print_flag
==
1
)
{
rte_eth_link_to_str
(
link_status_text
,
sizeof
(
link_status_text
),
&
link
);
printf
(
"Port %d %s
\n
"
,
portid
,
link_status_text
);
continue
;
}
/* clear all_ports_up flag if any link down */
if
(
link
.
link_status
==
ETH_LINK_DOWN
)
{
all_ports_up
=
0
;
break
;
}
}
/* after finally printing all link status, get out */
if
(
print_flag
==
1
)
break
;
if
(
all_ports_up
==
0
)
{
printf
(
"."
);
fflush
(
stdout
);
rte_delay_ms
(
CHECK_INTERVAL
);
}
/* set the print_flag if all ports up or timeout */
if
(
all_ports_up
==
1
||
count
==
(
MAX_CHECK_TIME
-
1
))
{
print_flag
=
1
;
printf
(
"done
\n
"
);
}
}
}
static
void
signal_handler
(
int
signum
)
{
if
(
signum
==
SIGINT
||
signum
==
SIGTERM
)
{
printf
(
"
\n\n
Signal %d received, preparing to exit...
\n
"
,
signum
);
force_quit
=
true
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
struct
lcore_queue_conf
*
qconf
;
int
ret
;
uint16_t
nb_ports
;
uint16_t
nb_ports_available
=
0
;
uint16_t
portid
,
last_port
;
unsigned
lcore_id
,
rx_lcore_id
;
unsigned
nb_ports_in_mask
=
0
;
unsigned
int
nb_lcores
=
0
;
unsigned
int
nb_mbufs
;
/* init EAL */
ret
=
rte_eal_init
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid EAL arguments
\n
"
);
argc
-=
ret
;
argv
+=
ret
;
force_quit
=
false
;
signal
(
SIGINT
,
signal_handler
);
signal
(
SIGTERM
,
signal_handler
);
/* parse application arguments (after the EAL ones) */
ret
=
l2fwd_parse_args
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid L2FWD arguments
\n
"
);
printf
(
"MAC updating %s
\n
"
,
mac_updating
?
"enabled"
:
"disabled"
);
/* convert to number of cycles */
timer_period
*=
rte_get_timer_hz
();
nb_ports
=
rte_eth_dev_count_avail
();
if
(
nb_ports
==
0
)
rte_exit
(
EXIT_FAILURE
,
"No Ethernet ports - bye
\n
"
);
if
(
port_pair_params
!=
NULL
)
{
if
(
check_port_pair_config
()
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid port pair config
\n
"
);
}
/* check port mask to possible port mask */
if
(
l2fwd_enabled_port_mask
&
~
((
1
<<
nb_ports
)
-
1
))
rte_exit
(
EXIT_FAILURE
,
"Invalid portmask; possible (0x%x)
\n
"
,
(
1
<<
nb_ports
)
-
1
);
/* reset l2fwd_dst_ports */
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
l2fwd_dst_ports
[
portid
]
=
0
;
last_port
=
0
;
/* populate destination port details */
if
(
port_pair_params
!=
NULL
)
{
uint16_t
idx
,
p
;
for
(
idx
=
0
;
idx
<
(
nb_port_pair_params
<<
1
);
idx
++
)
{
p
=
idx
&
1
;
portid
=
port_pair_params
[
idx
>>
1
].
port
[
p
];
l2fwd_dst_ports
[
portid
]
=
port_pair_params
[
idx
>>
1
].
port
[
p
^
1
];
}
}
else
{
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
if
(
nb_ports_in_mask
%
2
)
{
l2fwd_dst_ports
[
portid
]
=
last_port
;
l2fwd_dst_ports
[
last_port
]
=
portid
;
}
else
{
last_port
=
portid
;
}
nb_ports_in_mask
++
;
}
if
(
nb_ports_in_mask
%
2
)
{
printf
(
"Notice: odd number of ports in portmask.
\n
"
);
l2fwd_dst_ports
[
last_port
]
=
last_port
;
}
}
rx_lcore_id
=
0
;
qconf
=
NULL
;
/* Initialize the port/queue configuration of each logical core */
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
/* get the lcore_id for this port */
while
(
rte_lcore_is_enabled
(
rx_lcore_id
)
==
0
||
lcore_queue_conf
[
rx_lcore_id
].
n_rx_port
==
l2fwd_rx_queue_per_lcore
)
{
rx_lcore_id
++
;
if
(
rx_lcore_id
>=
RTE_MAX_LCORE
)
rte_exit
(
EXIT_FAILURE
,
"Not enough cores
\n
"
);
}
if
(
qconf
!=
&
lcore_queue_conf
[
rx_lcore_id
])
{
/* Assigned a new logical core in the loop above. */
qconf
=
&
lcore_queue_conf
[
rx_lcore_id
];
nb_lcores
++
;
}
qconf
->
rx_port_list
[
qconf
->
n_rx_port
]
=
portid
;
qconf
->
n_rx_port
++
;
printf
(
"Lcore %u: RX port %u TX port %u
\n
"
,
rx_lcore_id
,
portid
,
l2fwd_dst_ports
[
portid
]);
}
nb_mbufs
=
RTE_MAX
(
nb_ports
*
(
nb_rxd
+
nb_txd
+
MAX_PKT_BURST
+
nb_lcores
*
MEMPOOL_CACHE_SIZE
),
8192U
);
/* create the mbuf pool */
l2fwd_pktmbuf_pool
=
rte_pktmbuf_pool_create
(
"mbuf_pool"
,
nb_mbufs
,
MEMPOOL_CACHE_SIZE
,
0
,
RTE_MBUF_DEFAULT_BUF_SIZE
,
rte_socket_id
());
if
(
l2fwd_pktmbuf_pool
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot init mbuf pool
\n
"
);
/* Initialise each port */
RTE_ETH_FOREACH_DEV
(
portid
)
{
struct
rte_eth_rxconf
rxq_conf
;
struct
rte_eth_txconf
txq_conf
;
struct
rte_eth_conf
local_port_conf
=
port_conf
;
struct
rte_eth_dev_info
dev_info
;
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"Skipping disabled port %u
\n
"
,
portid
);
continue
;
}
nb_ports_available
++
;
/* init port */
printf
(
"Initializing port %u... "
,
portid
);
fflush
(
stdout
);
ret
=
rte_eth_dev_info_get
(
portid
,
&
dev_info
);
if
(
ret
!=
0
)
rte_exit
(
EXIT_FAILURE
,
"Error during getting device (port %u) info: %s
\n
"
,
portid
,
strerror
(
-
ret
));
if
(
dev_info
.
tx_offload_capa
&
DEV_TX_OFFLOAD_MBUF_FAST_FREE
)
local_port_conf
.
txmode
.
offloads
|=
DEV_TX_OFFLOAD_MBUF_FAST_FREE
;
ret
=
rte_eth_dev_configure
(
portid
,
1
,
1
,
&
local_port_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot configure device: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_dev_adjust_nb_rx_tx_desc
(
portid
,
&
nb_rxd
,
&
nb_txd
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot adjust number of descriptors: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_macaddr_get
(
portid
,
&
l2fwd_ports_eth_addr
[
portid
]);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot get MAC address: err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one RX queue */
fflush
(
stdout
);
rxq_conf
=
dev_info
.
default_rxconf
;
rxq_conf
.
offloads
=
local_port_conf
.
rxmode
.
offloads
;
ret
=
rte_eth_rx_queue_setup
(
portid
,
0
,
nb_rxd
,
rte_eth_dev_socket_id
(
portid
),
&
rxq_conf
,
l2fwd_pktmbuf_pool
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_rx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one TX queue on each port */
fflush
(
stdout
);
txq_conf
=
dev_info
.
default_txconf
;
txq_conf
.
offloads
=
local_port_conf
.
txmode
.
offloads
;
ret
=
rte_eth_tx_queue_setup
(
portid
,
0
,
nb_txd
,
rte_eth_dev_socket_id
(
portid
),
&
txq_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_tx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* Initialize TX buffers */
tx_buffer
[
portid
]
=
rte_zmalloc_socket
(
"tx_buffer"
,
RTE_ETH_TX_BUFFER_SIZE
(
MAX_PKT_BURST
),
0
,
rte_eth_dev_socket_id
(
portid
));
if
(
tx_buffer
[
portid
]
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot allocate buffer for tx on port %u
\n
"
,
portid
);
rte_eth_tx_buffer_init
(
tx_buffer
[
portid
],
MAX_PKT_BURST
);
ret
=
rte_eth_tx_buffer_set_err_callback
(
tx_buffer
[
portid
],
rte_eth_tx_buffer_count_callback
,
&
port_statistics
[
portid
].
dropped
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot set error callback for tx buffer on port %u
\n
"
,
portid
);
ret
=
rte_eth_dev_set_ptypes
(
portid
,
RTE_PTYPE_UNKNOWN
,
NULL
,
0
);
if
(
ret
<
0
)
printf
(
"Port %u, Failed to disable Ptype parsing
\n
"
,
portid
);
/* Start device */
ret
=
rte_eth_dev_start
(
portid
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_dev_start:err=%d, port=%u
\n
"
,
ret
,
portid
);
printf
(
"done:
\n
"
);
ret
=
rte_eth_promiscuous_enable
(
portid
);
if
(
ret
!=
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_promiscuous_enable:err=%s, port=%u
\n
"
,
rte_strerror
(
-
ret
),
portid
);
printf
(
"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X
\n\n
"
,
portid
,
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
0
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
1
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
2
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
3
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
4
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
5
]);
/* initialize port stats */
memset
(
&
port_statistics
,
0
,
sizeof
(
port_statistics
));
}
if
(
!
nb_ports_available
)
{
rte_exit
(
EXIT_FAILURE
,
"All available ports are disabled. Please set portmask.
\n
"
);
}
check_all_ports_link_status
(
l2fwd_enabled_port_mask
);
ret
=
0
;
/* launch per-lcore init on every lcore */
rte_eal_mp_remote_launch
(
l2fwd_launch_one_lcore
,
NULL
,
CALL_MAIN
);
RTE_LCORE_FOREACH_WORKER
(
lcore_id
)
{
if
(
rte_eal_wait_lcore
(
lcore_id
)
<
0
)
{
ret
=
-
1
;
break
;
}
}
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"Closing port %d..."
,
portid
);
ret
=
rte_eth_dev_stop
(
portid
);
if
(
ret
!=
0
)
printf
(
"rte_eth_dev_stop: err=%d, port=%d
\n
"
,
ret
,
portid
);
rte_eth_dev_close
(
portid
);
printf
(
" Done
\n
"
);
}
printf
(
"Bye...
\n
"
);
print_table
(
ht
);
free_table
(
ht
);
return
ret
;
}
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/main.c
0 → 100644
View file @
f7053183
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2016 Intel Corporation
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_string_fns.h>
#include <rte_udp.h>
#include <rte_ip.h>
#include <rte_hash.h>
#define CAPACITY 50000 // Size of the Hash Table
static
volatile
bool
force_quit
;
/* MAC updating enabled by default */
static
int
mac_updating
=
1
;
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 128 //64 //32
#define BURST_TX_DRAIN_US 50 //100 // TX drain every ~100us
#define MEMPOOL_CACHE_SIZE 512 //256
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static
uint16_t
nb_rxd
=
RTE_TEST_RX_DESC_DEFAULT
;
static
uint16_t
nb_txd
=
RTE_TEST_TX_DESC_DEFAULT
;
/* ethernet addresses of ports */
static
struct
rte_ether_addr
l2fwd_ports_eth_addr
[
RTE_MAX_ETHPORTS
];
/* mask of enabled ports */
static
uint32_t
l2fwd_enabled_port_mask
=
0
;
/* list of enabled ports */
static
uint32_t
l2fwd_dst_ports
[
RTE_MAX_ETHPORTS
];
struct
port_pair_params
{
#define NUM_PORTS 2
uint16_t
port
[
NUM_PORTS
];
}
__rte_cache_aligned
;
static
struct
port_pair_params
port_pair_params_array
[
RTE_MAX_ETHPORTS
/
2
];
static
struct
port_pair_params
*
port_pair_params
;
static
uint16_t
nb_port_pair_params
;
static
unsigned
int
l2fwd_rx_queue_per_lcore
=
1
;
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_TX_QUEUE_PER_PORT 16
struct
lcore_queue_conf
{
unsigned
n_rx_port
;
unsigned
rx_port_list
[
MAX_RX_QUEUE_PER_LCORE
];
}
__rte_cache_aligned
;
struct
lcore_queue_conf
lcore_queue_conf
[
RTE_MAX_LCORE
];
static
struct
rte_eth_dev_tx_buffer
*
tx_buffer
[
RTE_MAX_ETHPORTS
];
static
struct
rte_eth_conf
port_conf
=
{
.
rxmode
=
{
.
split_hdr_size
=
0
,
},
.
txmode
=
{
.
mq_mode
=
ETH_MQ_TX_NONE
,
},
};
struct
rte_mempool
*
l2fwd_pktmbuf_pool
=
NULL
;
/* Per-port statistics struct */
struct
l2fwd_port_statistics
{
uint64_t
tx
;
uint64_t
rx
;
uint64_t
dropped
;
}
__rte_cache_aligned
;
struct
l2fwd_port_statistics
port_statistics
[
RTE_MAX_ETHPORTS
];
#define MAX_TIMER_PERIOD 86400
/* 1 day max */
/* A tsc-based timer responsible for triggering statistics printout */
static
uint64_t
timer_period
=
10
;
/* default period is 10 seconds */
struct
pkt_data
{
uint16_t
type
;
uint16_t
sep1
;
uint16_t
sep2
;
uint16_t
sep3
;
uint32_t
key
;
uint16_t
sep4
;
uint16_t
sep5
;
uint16_t
sep6
;
uint32_t
val
;
//char pad1[8];
};
struct
HashTable
*
ht
;
/* Print out statistics on packets dropped */
static
void
print_stats
(
void
)
{
uint64_t
total_packets_dropped
,
total_packets_tx
,
total_packets_rx
;
unsigned
portid
;
total_packets_dropped
=
0
;
total_packets_tx
=
0
;
total_packets_rx
=
0
;
const
char
clr
[]
=
{
27
,
'['
,
'2'
,
'J'
,
'\0'
};
const
char
topLeft
[]
=
{
27
,
'['
,
'1'
,
';'
,
'1'
,
'H'
,
'\0'
};
/* Clear screen and move to top left */
printf
(
"%s%s"
,
clr
,
topLeft
);
printf
(
"
\n
Port statistics ===================================="
);
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
{
/* skip disabled ports */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"
\n
Statistics for port %u ------------------------------"
"
\n
Packets sent: %24"
PRIu64
"
\n
Packets received: %20"
PRIu64
"
\n
Packets dropped: %21"
PRIu64
,
portid
,
port_statistics
[
portid
].
tx
,
port_statistics
[
portid
].
rx
,
port_statistics
[
portid
].
dropped
);
total_packets_dropped
+=
port_statistics
[
portid
].
dropped
;
total_packets_tx
+=
port_statistics
[
portid
].
tx
;
total_packets_rx
+=
port_statistics
[
portid
].
rx
;
}
printf
(
"
\n
Aggregate statistics ==============================="
"
\n
Total packets sent: %18"
PRIu64
"
\n
Total packets received: %14"
PRIu64
"
\n
Total packets dropped: %15"
PRIu64
,
total_packets_tx
,
total_packets_rx
,
total_packets_dropped
);
printf
(
"
\n
====================================================
\n
"
);
fflush
(
stdout
);
}
unsigned
long
hash_function
(
char
*
str
)
{
unsigned
long
i
=
0
;
for
(
int
j
=
0
;
str
[
j
];
j
++
)
i
+=
str
[
j
];
return
i
%
CAPACITY
;
}
typedef
struct
Ht_item
Ht_item
;
// Define the Hash Table Item here
struct
Ht_item
{
char
*
key
;
char
*
value
;
};
typedef
struct
LinkedList
LinkedList
;
// Define the Linkedlist here
struct
LinkedList
{
Ht_item
*
item
;
LinkedList
*
next
;
};
typedef
struct
HashTable
HashTable
;
// Define the Hash Table here
struct
HashTable
{
// Contains an array of pointers
// to items
Ht_item
**
items
;
LinkedList
**
overflow_buckets
;
int
size
;
int
count
;
};
static
LinkedList
*
allocate_list
()
{
// Allocates memory for a Linkedlist pointer
LinkedList
*
list
=
(
LinkedList
*
)
malloc
(
sizeof
(
LinkedList
));
return
list
;
}
static
LinkedList
*
linkedlist_insert
(
LinkedList
*
list
,
Ht_item
*
item
)
{
// Inserts the item onto the Linked List
if
(
!
list
)
{
LinkedList
*
head
=
allocate_list
();
head
->
item
=
item
;
head
->
next
=
NULL
;
list
=
head
;
return
list
;
}
else
if
(
list
->
next
==
NULL
)
{
LinkedList
*
node
=
allocate_list
();
node
->
item
=
item
;
node
->
next
=
NULL
;
list
->
next
=
node
;
return
list
;
}
LinkedList
*
temp
=
list
;
// @rinku
while
(
temp
->
next
)
{
//->next) {
temp
=
temp
->
next
;
}
LinkedList
*
node
=
allocate_list
();
node
->
item
=
item
;
node
->
next
=
NULL
;
temp
->
next
=
node
;
return
list
;
}
static
Ht_item
*
linkedlist_remove
(
LinkedList
*
list
)
{
// Removes the head from the linked list
// and returns the item of the popped element
if
(
!
list
)
return
NULL
;
if
(
!
list
->
next
)
return
NULL
;
LinkedList
*
node
=
list
->
next
;
LinkedList
*
temp
=
list
;
temp
->
next
=
NULL
;
list
=
node
;
Ht_item
*
it
=
NULL
;
memcpy
(
temp
->
item
,
it
,
sizeof
(
Ht_item
));
free
(
temp
->
item
->
key
);
free
(
temp
->
item
->
value
);
free
(
temp
->
item
);
free
(
temp
);
return
it
;
}
static
void
free_linkedlist
(
LinkedList
*
list
)
{
LinkedList
*
temp
=
list
;
while
(
list
)
{
temp
=
list
;
list
=
list
->
next
;
free
(
temp
->
item
->
key
);
free
(
temp
->
item
->
value
);
free
(
temp
->
item
);
free
(
temp
);
}
}
static
LinkedList
**
create_overflow_buckets
(
HashTable
*
table
)
{
// Create the overflow buckets; an array of linkedlists
LinkedList
**
buckets
=
(
LinkedList
**
)
calloc
(
table
->
size
,
sizeof
(
LinkedList
*
));
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
buckets
[
i
]
=
NULL
;
return
buckets
;
}
static
void
free_overflow_buckets
(
HashTable
*
table
)
{
// Free all the overflow bucket lists
LinkedList
**
buckets
=
table
->
overflow_buckets
;
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
free_linkedlist
(
buckets
[
i
]);
free
(
buckets
);
}
Ht_item
*
create_item
(
char
*
key
,
char
*
value
)
{
// Creates a pointer to a new hash table item
Ht_item
*
item
=
(
Ht_item
*
)
malloc
(
sizeof
(
Ht_item
));
item
->
key
=
(
char
*
)
malloc
(
strlen
(
key
)
+
1
);
item
->
value
=
(
char
*
)
malloc
(
strlen
(
value
)
+
1
);
strcpy
(
item
->
key
,
key
);
strcpy
(
item
->
value
,
value
);
return
item
;
}
HashTable
*
create_table
(
int
size
)
{
// Creates a new HashTable
HashTable
*
table
=
(
HashTable
*
)
malloc
(
sizeof
(
HashTable
));
table
->
size
=
size
;
table
->
count
=
0
;
table
->
items
=
(
Ht_item
**
)
calloc
(
table
->
size
,
sizeof
(
Ht_item
*
));
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
table
->
items
[
i
]
=
NULL
;
table
->
overflow_buckets
=
create_overflow_buckets
(
table
);
return
table
;
}
void
free_item
(
Ht_item
*
item
)
{
// Frees an item
free
(
item
->
key
);
free
(
item
->
value
);
free
(
item
);
}
void
free_table
(
HashTable
*
table
)
{
// Frees the table
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
{
Ht_item
*
item
=
table
->
items
[
i
];
if
(
item
!=
NULL
)
free_item
(
item
);
}
free_overflow_buckets
(
table
);
free
(
table
->
items
);
free
(
table
);
}
void
handle_collision
(
HashTable
*
table
,
unsigned
long
index
,
Ht_item
*
item
)
{
LinkedList
*
head
=
table
->
overflow_buckets
[
index
];
if
(
head
==
NULL
)
{
// We need to create the list
head
=
allocate_list
();
head
->
item
=
item
;
table
->
overflow_buckets
[
index
]
=
head
;
return
;
}
else
{
// Insert to the list
table
->
overflow_buckets
[
index
]
=
linkedlist_insert
(
head
,
item
);
return
;
}
}
void
ht_insert
(
HashTable
*
table
,
char
*
key
,
char
*
value
)
{
// Create the item
Ht_item
*
item
=
create_item
(
key
,
value
);
// Compute the index
unsigned
long
index
=
hash_function
(
key
);
Ht_item
*
current_item
=
table
->
items
[
index
];
//if (strcmp(key,"1234") == 0)
// printf("%s %s %ld \n", key, value, index);
if
(
current_item
==
NULL
)
{
// Key does not exist.
if
(
table
->
count
==
table
->
size
)
{
// Hash Table Full
printf
(
"Insert Error: Hash Table is full
\n
"
);
// Remove the create item
free_item
(
item
);
return
;
}
// Insert directly
table
->
items
[
index
]
=
item
;
table
->
count
++
;
}
else
{
// Scenario 1: We only need to update value
if
(
strcmp
(
current_item
->
key
,
key
)
==
0
)
{
strcpy
(
table
->
items
[
index
]
->
value
,
value
);
return
;
}
else
{
// Scenario 2: Collision
handle_collision
(
table
,
index
,
item
);
return
;
}
}
}
char
*
ht_search
(
HashTable
*
table
,
char
*
key
)
{
// Searches the key in the hashtable
// and returns NULL if it doesn't exist
int
index
=
hash_function
(
key
);
Ht_item
*
item
=
table
->
items
[
index
];
LinkedList
*
head
=
table
->
overflow_buckets
[
index
];
// Ensure that we move to items which are not NULL
while
(
item
!=
NULL
)
{
if
(
strcmp
(
item
->
key
,
key
)
==
0
)
return
item
->
value
;
if
(
head
==
NULL
)
return
NULL
;
item
=
head
->
item
;
head
=
head
->
next
;
}
return
NULL
;
}
void
ht_delete
(
HashTable
*
table
,
char
*
key
)
{
// Deletes an item from the table
int
index
=
hash_function
(
key
);
Ht_item
*
item
=
table
->
items
[
index
];
LinkedList
*
head
=
table
->
overflow_buckets
[
index
];
if
(
item
==
NULL
)
{
// Does not exist. Return
return
;
}
else
{
if
(
head
==
NULL
&&
strcmp
(
item
->
key
,
key
)
==
0
)
{
// No collision chain. Remove the item
// and set table index to NULL
table
->
items
[
index
]
=
NULL
;
free_item
(
item
);
table
->
count
--
;
return
;
}
else
if
(
head
!=
NULL
)
{
// Collision Chain exists
if
(
strcmp
(
item
->
key
,
key
)
==
0
)
{
// Remove this item and set the head of the list
// as the new item
free_item
(
item
);
LinkedList
*
node
=
head
;
head
=
head
->
next
;
node
->
next
=
NULL
;
table
->
items
[
index
]
=
create_item
(
node
->
item
->
key
,
node
->
item
->
value
);
free_linkedlist
(
node
);
table
->
overflow_buckets
[
index
]
=
head
;
return
;
}
LinkedList
*
curr
=
head
;
LinkedList
*
prev
=
NULL
;
while
(
curr
)
{
if
(
strcmp
(
curr
->
item
->
key
,
key
)
==
0
)
{
if
(
prev
==
NULL
)
{
// First element of the chain. Remove the chain
free_linkedlist
(
head
);
table
->
overflow_buckets
[
index
]
=
NULL
;
return
;
}
else
{
// This is somewhere in the chain
prev
->
next
=
curr
->
next
;
curr
->
next
=
NULL
;
free_linkedlist
(
curr
);
table
->
overflow_buckets
[
index
]
=
head
;
return
;
}
}
curr
=
curr
->
next
;
prev
=
curr
;
}
}
}
}
void
print_search
(
HashTable
*
table
,
char
*
key
)
{
char
*
val
;
if
((
val
=
ht_search
(
table
,
key
))
==
NULL
)
{
printf
(
"%s does not exist
\n
"
,
key
);
return
;
}
else
{
printf
(
"Key:%s, Value:%s
\n
"
,
key
,
val
);
}
}
char
*
return_search
(
HashTable
*
table
,
char
*
key
)
{
char
*
val
;
if
((
val
=
ht_search
(
table
,
key
))
==
NULL
)
{
//printf("%s does not exist\n", key);
return
"0"
;
}
else
{
//printf("Key:%s, Value:%s\n", key, val);
return
val
;
}
}
void
print_table
(
HashTable
*
table
)
{
printf
(
"
\n
-------------------
\n
"
);
for
(
int
i
=
0
;
i
<
table
->
size
;
i
++
)
{
if
(
table
->
items
[
i
])
{
printf
(
"Index:%d, Key:%s, Value:%s"
,
i
,
table
->
items
[
i
]
->
key
,
table
->
items
[
i
]
->
value
);
if
(
table
->
overflow_buckets
[
i
])
{
printf
(
" => Overflow Bucket => "
);
LinkedList
*
head
=
table
->
overflow_buckets
[
i
];
while
(
head
)
{
printf
(
"Key:%s, Value:%s "
,
head
->
item
->
key
,
head
->
item
->
value
);
head
=
head
->
next
;
}
}
printf
(
"
\n
"
);
}
}
printf
(
"-------------------
\n
"
);
}
static
void
l2fwd_mac_updating
(
struct
rte_mbuf
*
m
,
unsigned
dest_portid
)
{
struct
rte_ether_hdr
*
eth
;
void
*
tmp
;
//struct pkt_data *data;
eth
=
rte_pktmbuf_mtod
(
m
,
struct
rte_ether_hdr
*
);
/* 02:00:00:00:00:xx */
/* 0c:42:a1:df:ac:40 41 */
tmp
=
&
eth
->
d_addr
.
addr_bytes
[
0
];
// @rinku
//*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);
*
((
uint64_t
*
)
tmp
)
=
0x40acdfa1420c
+
((
uint64_t
)
dest_portid
<<
56
);
/* src addr */
rte_ether_addr_copy
(
&
l2fwd_ports_eth_addr
[
dest_portid
],
&
eth
->
s_addr
);
// @rinku
struct
rte_ipv4_hdr
*
ipv4_hdr
;
if
(
RTE_ETH_IS_IPV4_HDR
(
m
->
packet_type
))
{
ipv4_hdr
=
rte_pktmbuf_mtod_offset
(
m
,
struct
rte_ipv4_hdr
*
,
sizeof
(
struct
rte_ether_hdr
));
uint32_t
tmp_dst
;
tmp_dst
=
ipv4_hdr
->
src_addr
;
ipv4_hdr
->
src_addr
=
ipv4_hdr
->
dst_addr
;
ipv4_hdr
->
dst_addr
=
tmp_dst
;
}
// @rinku
struct
rte_udp_hdr
*
udp
;
struct
pkt_data
*
data
;
if
(
ipv4_hdr
->
next_proto_id
==
IPPROTO_UDP
)
{
udp
=
(
struct
rte_udp_hdr
*
)((
unsigned
char
*
)
ipv4_hdr
+
sizeof
(
struct
rte_ipv4_hdr
));
uint16_t
port_dst
=
udp
->
dst_port
;
udp
->
dst_port
=
udp
->
src_port
;
udp
->
src_port
=
port_dst
;
//printf("len= %d ", ntohs(udp->dgram_len));
data
=
(
struct
pkt_data
*
)
((
unsigned
char
*
)
udp
+
sizeof
(
struct
rte_udp_hdr
));
if
((
data
!=
NULL
)
&&
(
ntohs
(
data
->
type
)
==
4
))
{
//if (data != NULL) {
//printf("len= %d ", udp->dgram_len);
//printf("%x %x %x %x %d %x %x %x %d \n",ntohs(data->type), ntohs(data->sep1), ntohs(data->sep2), ntohs(data->sep3), ntohl(data->key), ntohs(data->sep4), ntohs(data->sep5), ntohs(data->sep6),ntohl(data->val));
//printf("key= %d val= %d \n",ntohl(data->key),ntohs(data->val));
char
k
[
6
];
// v[6];
sprintf
(
k
,
"%d"
,
ntohl
(
data
->
key
));
char
*
v
=
return_search
(
ht
,
k
);
uint32_t
tmp_val
=
atoi
(
v
);
//sprintf(tmp_val, "%s", v);
data
->
val
=
htons
(
tmp_val
);
//sprintf(data->pad1, "%d", 12345678);
}
}
}
static
void
l2fwd_simple_forward
(
struct
rte_mbuf
*
m
,
unsigned
portid
)
{
unsigned
dst_port
;
int
sent
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
dst_port
=
l2fwd_dst_ports
[
portid
];
//printf("DEST PORT = %u", dst_port);
//@rinku
/*if (dst_port == 0)
dst_port = 1;
else if (dst_port == 1)
dst_port = 0;*/
if
(
mac_updating
)
l2fwd_mac_updating
(
m
,
dst_port
);
buffer
=
tx_buffer
[
dst_port
];
sent
=
rte_eth_tx_buffer
(
dst_port
,
0
,
buffer
,
m
);
if
(
sent
)
port_statistics
[
dst_port
].
tx
+=
sent
;
}
// @rinku
// Function to convert integer to
// character array
/* char* convertIntegerToChar(int N)
{
// Count digits in number N
int m = N;
int digit = 0;
while (m) {
// Increment number of digits
digit++;
// Truncate the last
// digit from the number
m /= 10;
}
// Declare char array for result
char* arr;
// Declare duplicate char array
char arr1[digit];
// Memory allocaton of array
arr = (char*)malloc(digit);
// Separating integer into digits and
// accomodate it to character array
int index = 0;
while (N) {
// Separate last digit from
// the number and add ASCII
// value of character '0' is 48
arr1[++index] = N % 10 + '0';
// Truncate the last
// digit from the number
N /= 10;
}
// Reverse the array for result
int i;
for (i = 0; i < index; i++) {
arr[i] = arr1[index - i];
}
// Char array truncate by null
arr[i] = '\0';
// Return char array
return (char*)arr;
}*/
/* main processing loop */
static
void
l2fwd_main_loop
(
void
)
{
struct
rte_mbuf
*
pkts_burst
[
MAX_PKT_BURST
];
struct
rte_mbuf
*
m
;
int
sent
;
unsigned
lcore_id
;
uint64_t
prev_tsc
,
diff_tsc
,
cur_tsc
,
timer_tsc
;
unsigned
i
,
j
,
portid
,
nb_rx
;
struct
lcore_queue_conf
*
qconf
;
const
uint64_t
drain_tsc
=
(
rte_get_tsc_hz
()
+
US_PER_S
-
1
)
/
US_PER_S
*
BURST_TX_DRAIN_US
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
prev_tsc
=
0
;
timer_tsc
=
0
;
lcore_id
=
rte_lcore_id
();
qconf
=
&
lcore_queue_conf
[
lcore_id
];
if
(
qconf
->
n_rx_port
==
0
)
{
RTE_LOG
(
INFO
,
L2FWD
,
"lcore %u has nothing to do
\n
"
,
lcore_id
);
return
;
}
RTE_LOG
(
INFO
,
L2FWD
,
"entering main loop on lcore %u
\n
"
,
lcore_id
);
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
RTE_LOG
(
INFO
,
L2FWD
,
" -- lcoreid=%u portid=%u
\n
"
,
lcore_id
,
portid
);
}
ht
=
create_table
(
CAPACITY
);
//ht_insert(ht,"1234","1235");
for
(
int
i
=
0
;
i
<
CAPACITY
;
i
++
){
char
k
[
7
],
v
[
7
];
int
val
=
i
+
1
;
sprintf
(
k
,
"%d"
,
i
);
sprintf
(
v
,
"%d"
,
val
);
ht_insert
(
ht
,
k
,
v
);
}
print_search
(
ht
,
"1234"
);
/*print_search(ht, "1");
print_search(ht, "2");
print_search(ht, "3");
print_table(ht);
free_table(ht);*/
while
(
!
force_quit
)
{
cur_tsc
=
rte_rdtsc
();
/*
* TX burst queue drain
*/
diff_tsc
=
cur_tsc
-
prev_tsc
;
if
(
unlikely
(
diff_tsc
>
drain_tsc
))
{
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
l2fwd_dst_ports
[
qconf
->
rx_port_list
[
i
]];
buffer
=
tx_buffer
[
portid
];
sent
=
rte_eth_tx_buffer_flush
(
portid
,
0
,
buffer
);
if
(
sent
)
port_statistics
[
portid
].
tx
+=
sent
;
}
/* if timer is enabled */
if
(
timer_period
>
0
)
{
/* advance the timer */
timer_tsc
+=
diff_tsc
;
/* if timer has reached its timeout */
if
(
unlikely
(
timer_tsc
>=
timer_period
))
{
/* do this only on main core */
if
(
lcore_id
==
rte_get_main_lcore
())
{
print_stats
();
/* reset the timer */
timer_tsc
=
0
;
}
}
}
prev_tsc
=
cur_tsc
;
}
/*
* Read packet from RX queues
*/
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
nb_rx
=
rte_eth_rx_burst
(
portid
,
0
,
pkts_burst
,
MAX_PKT_BURST
);
port_statistics
[
portid
].
rx
+=
nb_rx
;
for
(
j
=
0
;
j
<
nb_rx
;
j
++
)
{
m
=
pkts_burst
[
j
];
rte_prefetch0
(
rte_pktmbuf_mtod
(
m
,
void
*
));
l2fwd_simple_forward
(
m
,
portid
);
}
}
}
}
static
int
l2fwd_launch_one_lcore
(
__rte_unused
void
*
dummy
)
{
l2fwd_main_loop
();
return
0
;
}
/* display usage */
static
void
l2fwd_usage
(
const
char
*
prgname
)
{
printf
(
"%s [EAL options] -- -p PORTMASK [-q NQ]
\n
"
" -p PORTMASK: hexadecimal bitmask of ports to configure
\n
"
" -q NQ: number of queue (=ports) per lcore (default is 1)
\n
"
" -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)
\n
"
" --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)
\n
"
" When enabled:
\n
"
" - The source MAC address is replaced by the TX port MAC address
\n
"
" - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID
\n
"
" --portmap: Configure forwarding port pair mapping
\n
"
" Default: alternate port pairs
\n\n
"
,
prgname
);
}
static
int
l2fwd_parse_portmask
(
const
char
*
portmask
)
{
char
*
end
=
NULL
;
unsigned
long
pm
;
/* parse hexadecimal string */
pm
=
strtoul
(
portmask
,
&
end
,
16
);
if
((
portmask
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
return
pm
;
}
static
int
l2fwd_parse_port_pair_config
(
const
char
*
q_arg
)
{
enum
fieldnames
{
FLD_PORT1
=
0
,
FLD_PORT2
,
_NUM_FLD
};
unsigned
long
int_fld
[
_NUM_FLD
];
const
char
*
p
,
*
p0
=
q_arg
;
char
*
str_fld
[
_NUM_FLD
];
unsigned
int
size
;
char
s
[
256
];
char
*
end
;
int
i
;
nb_port_pair_params
=
0
;
while
((
p
=
strchr
(
p0
,
'('
))
!=
NULL
)
{
++
p
;
p0
=
strchr
(
p
,
')'
);
if
(
p0
==
NULL
)
return
-
1
;
size
=
p0
-
p
;
if
(
size
>=
sizeof
(
s
))
return
-
1
;
memcpy
(
s
,
p
,
size
);
s
[
size
]
=
'\0'
;
if
(
rte_strsplit
(
s
,
sizeof
(
s
),
str_fld
,
_NUM_FLD
,
','
)
!=
_NUM_FLD
)
return
-
1
;
for
(
i
=
0
;
i
<
_NUM_FLD
;
i
++
)
{
errno
=
0
;
int_fld
[
i
]
=
strtoul
(
str_fld
[
i
],
&
end
,
0
);
if
(
errno
!=
0
||
end
==
str_fld
[
i
]
||
int_fld
[
i
]
>=
RTE_MAX_ETHPORTS
)
return
-
1
;
}
if
(
nb_port_pair_params
>=
RTE_MAX_ETHPORTS
/
2
)
{
printf
(
"exceeded max number of port pair params: %hu
\n
"
,
nb_port_pair_params
);
return
-
1
;
}
port_pair_params_array
[
nb_port_pair_params
].
port
[
0
]
=
(
uint16_t
)
int_fld
[
FLD_PORT1
];
port_pair_params_array
[
nb_port_pair_params
].
port
[
1
]
=
(
uint16_t
)
int_fld
[
FLD_PORT2
];
++
nb_port_pair_params
;
}
port_pair_params
=
port_pair_params_array
;
return
0
;
}
static
unsigned
int
l2fwd_parse_nqueue
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
unsigned
long
n
;
/* parse hexadecimal string */
n
=
strtoul
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
if
(
n
==
0
)
return
0
;
if
(
n
>=
MAX_RX_QUEUE_PER_LCORE
)
return
0
;
return
n
;
}
static
int
l2fwd_parse_timer_period
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
int
n
;
/* parse number string */
n
=
strtol
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
-
1
;
if
(
n
>=
MAX_TIMER_PERIOD
)
return
-
1
;
return
n
;
}
static
const
char
short_options
[]
=
"p:"
/* portmask */
"q:"
/* number of queues */
"T:"
/* timer period */
;
#define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
#define CMD_LINE_OPT_PORTMAP_CONFIG "portmap"
enum
{
/* long options mapped to a short option */
/* first long only option value must be >= 256, so that we won't
* conflict with short options */
CMD_LINE_OPT_MIN_NUM
=
256
,
CMD_LINE_OPT_PORTMAP_NUM
,
};
static
const
struct
option
lgopts
[]
=
{
{
CMD_LINE_OPT_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
1
},
{
CMD_LINE_OPT_NO_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
0
},
{
CMD_LINE_OPT_PORTMAP_CONFIG
,
1
,
0
,
CMD_LINE_OPT_PORTMAP_NUM
},
{
NULL
,
0
,
0
,
0
}
};
/* Parse the argument given in the command line of the application */
static
int
l2fwd_parse_args
(
int
argc
,
char
**
argv
)
{
int
opt
,
ret
,
timer_secs
;
char
**
argvopt
;
int
option_index
;
char
*
prgname
=
argv
[
0
];
argvopt
=
argv
;
port_pair_params
=
NULL
;
while
((
opt
=
getopt_long
(
argc
,
argvopt
,
short_options
,
lgopts
,
&
option_index
))
!=
EOF
)
{
switch
(
opt
)
{
/* portmask */
case
'p'
:
l2fwd_enabled_port_mask
=
l2fwd_parse_portmask
(
optarg
);
if
(
l2fwd_enabled_port_mask
==
0
)
{
printf
(
"invalid portmask
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* nqueue */
case
'q'
:
l2fwd_rx_queue_per_lcore
=
l2fwd_parse_nqueue
(
optarg
);
if
(
l2fwd_rx_queue_per_lcore
==
0
)
{
printf
(
"invalid queue number
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* timer period */
case
'T'
:
timer_secs
=
l2fwd_parse_timer_period
(
optarg
);
if
(
timer_secs
<
0
)
{
printf
(
"invalid timer period
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
timer_period
=
timer_secs
;
break
;
/* long options */
case
CMD_LINE_OPT_PORTMAP_NUM
:
ret
=
l2fwd_parse_port_pair_config
(
optarg
);
if
(
ret
)
{
fprintf
(
stderr
,
"Invalid config
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
default:
l2fwd_usage
(
prgname
);
return
-
1
;
}
}
if
(
optind
>=
0
)
argv
[
optind
-
1
]
=
prgname
;
ret
=
optind
-
1
;
optind
=
1
;
/* reset getopt lib */
return
ret
;
}
/*
* Check port pair config with enabled port mask,
* and for valid port pair combinations.
*/
static
int
check_port_pair_config
(
void
)
{
uint32_t
port_pair_config_mask
=
0
;
uint32_t
port_pair_mask
=
0
;
uint16_t
index
,
i
,
portid
;
for
(
index
=
0
;
index
<
nb_port_pair_params
;
index
++
)
{
port_pair_mask
=
0
;
for
(
i
=
0
;
i
<
NUM_PORTS
;
i
++
)
{
portid
=
port_pair_params
[
index
].
port
[
i
];
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"port %u is not enabled in port mask
\n
"
,
portid
);
return
-
1
;
}
if
(
!
rte_eth_dev_is_valid_port
(
portid
))
{
printf
(
"port %u is not present on the board
\n
"
,
portid
);
return
-
1
;
}
port_pair_mask
|=
1
<<
portid
;
}
if
(
port_pair_config_mask
&
port_pair_mask
)
{
printf
(
"port %u is used in other port pairs
\n
"
,
portid
);
return
-
1
;
}
port_pair_config_mask
|=
port_pair_mask
;
}
l2fwd_enabled_port_mask
&=
port_pair_config_mask
;
return
0
;
}
/* Check the link status of all ports in up to 9s, and print them finally */
static
void
check_all_ports_link_status
(
uint32_t
port_mask
)
{
#define CHECK_INTERVAL 100
/* 100ms */
#define MAX_CHECK_TIME 90
/* 9s (90 * 100ms) in total */
uint16_t
portid
;
uint8_t
count
,
all_ports_up
,
print_flag
=
0
;
struct
rte_eth_link
link
;
int
ret
;
char
link_status_text
[
RTE_ETH_LINK_MAX_STR_LEN
];
printf
(
"
\n
Checking link status"
);
fflush
(
stdout
);
for
(
count
=
0
;
count
<=
MAX_CHECK_TIME
;
count
++
)
{
if
(
force_quit
)
return
;
all_ports_up
=
1
;
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
(
force_quit
)
return
;
if
((
port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
memset
(
&
link
,
0
,
sizeof
(
link
));
ret
=
rte_eth_link_get_nowait
(
portid
,
&
link
);
if
(
ret
<
0
)
{
all_ports_up
=
0
;
if
(
print_flag
==
1
)
printf
(
"Port %u link get failed: %s
\n
"
,
portid
,
rte_strerror
(
-
ret
));
continue
;
}
/* print link status if flag set */
if
(
print_flag
==
1
)
{
rte_eth_link_to_str
(
link_status_text
,
sizeof
(
link_status_text
),
&
link
);
printf
(
"Port %d %s
\n
"
,
portid
,
link_status_text
);
continue
;
}
/* clear all_ports_up flag if any link down */
if
(
link
.
link_status
==
ETH_LINK_DOWN
)
{
all_ports_up
=
0
;
break
;
}
}
/* after finally printing all link status, get out */
if
(
print_flag
==
1
)
break
;
if
(
all_ports_up
==
0
)
{
printf
(
"."
);
fflush
(
stdout
);
rte_delay_ms
(
CHECK_INTERVAL
);
}
/* set the print_flag if all ports up or timeout */
if
(
all_ports_up
==
1
||
count
==
(
MAX_CHECK_TIME
-
1
))
{
print_flag
=
1
;
printf
(
"done
\n
"
);
}
}
}
static
void
signal_handler
(
int
signum
)
{
if
(
signum
==
SIGINT
||
signum
==
SIGTERM
)
{
printf
(
"
\n\n
Signal %d received, preparing to exit...
\n
"
,
signum
);
force_quit
=
true
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
struct
lcore_queue_conf
*
qconf
;
int
ret
;
uint16_t
nb_ports
;
uint16_t
nb_ports_available
=
0
;
uint16_t
portid
,
last_port
;
unsigned
lcore_id
,
rx_lcore_id
;
unsigned
nb_ports_in_mask
=
0
;
unsigned
int
nb_lcores
=
0
;
unsigned
int
nb_mbufs
;
/* init EAL */
ret
=
rte_eal_init
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid EAL arguments
\n
"
);
argc
-=
ret
;
argv
+=
ret
;
force_quit
=
false
;
signal
(
SIGINT
,
signal_handler
);
signal
(
SIGTERM
,
signal_handler
);
/* parse application arguments (after the EAL ones) */
ret
=
l2fwd_parse_args
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid L2FWD arguments
\n
"
);
printf
(
"MAC updating %s
\n
"
,
mac_updating
?
"enabled"
:
"disabled"
);
/* convert to number of cycles */
timer_period
*=
rte_get_timer_hz
();
nb_ports
=
rte_eth_dev_count_avail
();
if
(
nb_ports
==
0
)
rte_exit
(
EXIT_FAILURE
,
"No Ethernet ports - bye
\n
"
);
if
(
port_pair_params
!=
NULL
)
{
if
(
check_port_pair_config
()
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid port pair config
\n
"
);
}
/* check port mask to possible port mask */
if
(
l2fwd_enabled_port_mask
&
~
((
1
<<
nb_ports
)
-
1
))
rte_exit
(
EXIT_FAILURE
,
"Invalid portmask; possible (0x%x)
\n
"
,
(
1
<<
nb_ports
)
-
1
);
/* reset l2fwd_dst_ports */
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
l2fwd_dst_ports
[
portid
]
=
0
;
last_port
=
0
;
/* populate destination port details */
if
(
port_pair_params
!=
NULL
)
{
uint16_t
idx
,
p
;
for
(
idx
=
0
;
idx
<
(
nb_port_pair_params
<<
1
);
idx
++
)
{
p
=
idx
&
1
;
portid
=
port_pair_params
[
idx
>>
1
].
port
[
p
];
l2fwd_dst_ports
[
portid
]
=
port_pair_params
[
idx
>>
1
].
port
[
p
^
1
];
}
}
else
{
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
if
(
nb_ports_in_mask
%
2
)
{
l2fwd_dst_ports
[
portid
]
=
last_port
;
l2fwd_dst_ports
[
last_port
]
=
portid
;
}
else
{
last_port
=
portid
;
}
nb_ports_in_mask
++
;
}
if
(
nb_ports_in_mask
%
2
)
{
printf
(
"Notice: odd number of ports in portmask.
\n
"
);
l2fwd_dst_ports
[
last_port
]
=
last_port
;
}
}
rx_lcore_id
=
0
;
qconf
=
NULL
;
/* Initialize the port/queue configuration of each logical core */
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
/* get the lcore_id for this port */
while
(
rte_lcore_is_enabled
(
rx_lcore_id
)
==
0
||
lcore_queue_conf
[
rx_lcore_id
].
n_rx_port
==
l2fwd_rx_queue_per_lcore
)
{
rx_lcore_id
++
;
if
(
rx_lcore_id
>=
RTE_MAX_LCORE
)
rte_exit
(
EXIT_FAILURE
,
"Not enough cores
\n
"
);
}
if
(
qconf
!=
&
lcore_queue_conf
[
rx_lcore_id
])
{
/* Assigned a new logical core in the loop above. */
qconf
=
&
lcore_queue_conf
[
rx_lcore_id
];
nb_lcores
++
;
}
qconf
->
rx_port_list
[
qconf
->
n_rx_port
]
=
portid
;
qconf
->
n_rx_port
++
;
printf
(
"Lcore %u: RX port %u TX port %u
\n
"
,
rx_lcore_id
,
portid
,
l2fwd_dst_ports
[
portid
]);
}
nb_mbufs
=
RTE_MAX
(
nb_ports
*
(
nb_rxd
+
nb_txd
+
MAX_PKT_BURST
+
nb_lcores
*
MEMPOOL_CACHE_SIZE
),
8192U
);
/* create the mbuf pool */
l2fwd_pktmbuf_pool
=
rte_pktmbuf_pool_create
(
"mbuf_pool"
,
nb_mbufs
,
MEMPOOL_CACHE_SIZE
,
0
,
RTE_MBUF_DEFAULT_BUF_SIZE
,
rte_socket_id
());
if
(
l2fwd_pktmbuf_pool
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot init mbuf pool
\n
"
);
/* Initialise each port */
RTE_ETH_FOREACH_DEV
(
portid
)
{
struct
rte_eth_rxconf
rxq_conf
;
struct
rte_eth_txconf
txq_conf
;
struct
rte_eth_conf
local_port_conf
=
port_conf
;
struct
rte_eth_dev_info
dev_info
;
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"Skipping disabled port %u
\n
"
,
portid
);
continue
;
}
nb_ports_available
++
;
/* init port */
printf
(
"Initializing port %u... "
,
portid
);
fflush
(
stdout
);
ret
=
rte_eth_dev_info_get
(
portid
,
&
dev_info
);
if
(
ret
!=
0
)
rte_exit
(
EXIT_FAILURE
,
"Error during getting device (port %u) info: %s
\n
"
,
portid
,
strerror
(
-
ret
));
if
(
dev_info
.
tx_offload_capa
&
DEV_TX_OFFLOAD_MBUF_FAST_FREE
)
local_port_conf
.
txmode
.
offloads
|=
DEV_TX_OFFLOAD_MBUF_FAST_FREE
;
ret
=
rte_eth_dev_configure
(
portid
,
1
,
1
,
&
local_port_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot configure device: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_dev_adjust_nb_rx_tx_desc
(
portid
,
&
nb_rxd
,
&
nb_txd
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot adjust number of descriptors: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_macaddr_get
(
portid
,
&
l2fwd_ports_eth_addr
[
portid
]);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot get MAC address: err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one RX queue */
fflush
(
stdout
);
rxq_conf
=
dev_info
.
default_rxconf
;
rxq_conf
.
offloads
=
local_port_conf
.
rxmode
.
offloads
;
ret
=
rte_eth_rx_queue_setup
(
portid
,
0
,
nb_rxd
,
rte_eth_dev_socket_id
(
portid
),
&
rxq_conf
,
l2fwd_pktmbuf_pool
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_rx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one TX queue on each port */
fflush
(
stdout
);
txq_conf
=
dev_info
.
default_txconf
;
txq_conf
.
offloads
=
local_port_conf
.
txmode
.
offloads
;
ret
=
rte_eth_tx_queue_setup
(
portid
,
0
,
nb_txd
,
rte_eth_dev_socket_id
(
portid
),
&
txq_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_tx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* Initialize TX buffers */
tx_buffer
[
portid
]
=
rte_zmalloc_socket
(
"tx_buffer"
,
RTE_ETH_TX_BUFFER_SIZE
(
MAX_PKT_BURST
),
0
,
rte_eth_dev_socket_id
(
portid
));
if
(
tx_buffer
[
portid
]
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot allocate buffer for tx on port %u
\n
"
,
portid
);
rte_eth_tx_buffer_init
(
tx_buffer
[
portid
],
MAX_PKT_BURST
);
ret
=
rte_eth_tx_buffer_set_err_callback
(
tx_buffer
[
portid
],
rte_eth_tx_buffer_count_callback
,
&
port_statistics
[
portid
].
dropped
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot set error callback for tx buffer on port %u
\n
"
,
portid
);
ret
=
rte_eth_dev_set_ptypes
(
portid
,
RTE_PTYPE_UNKNOWN
,
NULL
,
0
);
if
(
ret
<
0
)
printf
(
"Port %u, Failed to disable Ptype parsing
\n
"
,
portid
);
/* Start device */
ret
=
rte_eth_dev_start
(
portid
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_dev_start:err=%d, port=%u
\n
"
,
ret
,
portid
);
printf
(
"done:
\n
"
);
ret
=
rte_eth_promiscuous_enable
(
portid
);
if
(
ret
!=
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_promiscuous_enable:err=%s, port=%u
\n
"
,
rte_strerror
(
-
ret
),
portid
);
printf
(
"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X
\n\n
"
,
portid
,
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
0
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
1
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
2
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
3
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
4
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
5
]);
/* initialize port stats */
memset
(
&
port_statistics
,
0
,
sizeof
(
port_statistics
));
}
if
(
!
nb_ports_available
)
{
rte_exit
(
EXIT_FAILURE
,
"All available ports are disabled. Please set portmask.
\n
"
);
}
check_all_ports_link_status
(
l2fwd_enabled_port_mask
);
ret
=
0
;
/* launch per-lcore init on every lcore */
rte_eal_mp_remote_launch
(
l2fwd_launch_one_lcore
,
NULL
,
CALL_MAIN
);
RTE_LCORE_FOREACH_WORKER
(
lcore_id
)
{
if
(
rte_eal_wait_lcore
(
lcore_id
)
<
0
)
{
ret
=
-
1
;
break
;
}
}
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"Closing port %d..."
,
portid
);
ret
=
rte_eth_dev_stop
(
portid
);
if
(
ret
!=
0
)
printf
(
"rte_eth_dev_stop: err=%d, port=%d
\n
"
,
ret
,
portid
);
rte_eth_dev_close
(
portid
);
printf
(
" Done
\n
"
);
}
printf
(
"Bye...
\n
"
);
//print_table(ht);
free_table
(
ht
);
return
ret
;
}
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/kv-cache/meson.build
0 → 100644
View file @
f7053183
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
# meson file, for building this example as part of a main DPDK build.
#
# To build this example as a standalone application with an already-installed
# DPDK instance, use 'make'
# Enable experimental API flag as l2fwd uses rte_ethdev_set_ptype API
allow_experimental_apis = true
sources = files(
'main.c'
)
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/l2fwd/Makefile
0 → 100644
View file @
f7053183
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation
# binary name
APP
=
l2fwd
# all source are stored in SRCS-y
SRCS-y
:=
main.c
# Build using pkg-config variables if possible
ifneq
($(shell pkg-config --exists libdpdk && echo 0),0)
$(error
"no installation of DPDK found"
)
endif
all
:
shared
.PHONY
:
shared static
shared
:
build/$(APP)-shared
ln
-sf
$(APP)
-shared
build/
$(APP)
static
:
build/$(APP)-static
ln
-sf
$(APP)
-static
build/
$(APP)
PKGCONF
?=
pkg-config
PC_FILE
:=
$(
shell
$(PKGCONF)
--path
libdpdk 2>/dev/null
)
CFLAGS
+=
-O3
$(
shell
$(PKGCONF)
--cflags
libdpdk
)
# Add flag to allow experimental API as l2fwd uses rte_ethdev_set_ptype API
CFLAGS
+=
-DALLOW_EXPERIMENTAL_API
LDFLAGS_SHARED
=
$(
shell
$(PKGCONF)
--libs
libdpdk
)
LDFLAGS_STATIC
=
$(
shell
$(PKGCONF)
--static
--libs
libdpdk
)
build/$(APP)-shared
:
$(SRCS-y) Makefile $(PC_FILE) | build
$(CC)
$(CFLAGS)
$
(
SRCS-y
)
-o
$@
$(LDFLAGS)
$(LDFLAGS_SHARED)
build/$(APP)-static
:
$(SRCS-y) Makefile $(PC_FILE) | build
$(CC)
$(CFLAGS)
$
(
SRCS-y
)
-o
$@
$(LDFLAGS)
$(LDFLAGS_STATIC)
build
:
@
mkdir
-p
$@
.PHONY
:
clean
clean
:
rm
-f
build/
$(APP)
build/
$(APP)
-static
build/
$(APP)
-shared
test
-d
build
&&
rmdir
-p
build
||
true
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/l2fwd/main.c
0 → 100644
View file @
f7053183
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2016 Intel Corporation
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_string_fns.h>
#include <rte_udp.h>
#include <rte_ip.h>
static
volatile
bool
force_quit
;
/* MAC updating enabled by default */
static
int
mac_updating
=
1
;
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 100
/* TX drain every ~100us */
#define MEMPOOL_CACHE_SIZE 256
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static
uint16_t
nb_rxd
=
RTE_TEST_RX_DESC_DEFAULT
;
static
uint16_t
nb_txd
=
RTE_TEST_TX_DESC_DEFAULT
;
/* ethernet addresses of ports */
static
struct
rte_ether_addr
l2fwd_ports_eth_addr
[
RTE_MAX_ETHPORTS
];
/* mask of enabled ports */
static
uint32_t
l2fwd_enabled_port_mask
=
0
;
/* list of enabled ports */
static
uint32_t
l2fwd_dst_ports
[
RTE_MAX_ETHPORTS
];
struct
port_pair_params
{
#define NUM_PORTS 2
uint16_t
port
[
NUM_PORTS
];
}
__rte_cache_aligned
;
static
struct
port_pair_params
port_pair_params_array
[
RTE_MAX_ETHPORTS
/
2
];
static
struct
port_pair_params
*
port_pair_params
;
static
uint16_t
nb_port_pair_params
;
static
unsigned
int
l2fwd_rx_queue_per_lcore
=
1
;
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_TX_QUEUE_PER_PORT 16
struct
lcore_queue_conf
{
unsigned
n_rx_port
;
unsigned
rx_port_list
[
MAX_RX_QUEUE_PER_LCORE
];
}
__rte_cache_aligned
;
struct
lcore_queue_conf
lcore_queue_conf
[
RTE_MAX_LCORE
];
static
struct
rte_eth_dev_tx_buffer
*
tx_buffer
[
RTE_MAX_ETHPORTS
];
static
struct
rte_eth_conf
port_conf
=
{
.
rxmode
=
{
.
split_hdr_size
=
0
,
},
.
txmode
=
{
.
mq_mode
=
ETH_MQ_TX_NONE
,
},
};
struct
rte_mempool
*
l2fwd_pktmbuf_pool
=
NULL
;
/* Per-port statistics struct */
struct
l2fwd_port_statistics
{
uint64_t
tx
;
uint64_t
rx
;
uint64_t
dropped
;
}
__rte_cache_aligned
;
struct
l2fwd_port_statistics
port_statistics
[
RTE_MAX_ETHPORTS
];
#define MAX_TIMER_PERIOD 86400
/* 1 day max */
/* A tsc-based timer responsible for triggering statistics printout */
static
uint64_t
timer_period
=
10
;
/* default period is 10 seconds */
/* Print out statistics on packets dropped */
static
void
print_stats
(
void
)
{
uint64_t
total_packets_dropped
,
total_packets_tx
,
total_packets_rx
;
unsigned
portid
;
total_packets_dropped
=
0
;
total_packets_tx
=
0
;
total_packets_rx
=
0
;
const
char
clr
[]
=
{
27
,
'['
,
'2'
,
'J'
,
'\0'
};
const
char
topLeft
[]
=
{
27
,
'['
,
'1'
,
';'
,
'1'
,
'H'
,
'\0'
};
/* Clear screen and move to top left */
printf
(
"%s%s"
,
clr
,
topLeft
);
printf
(
"
\n
Port statistics ===================================="
);
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
{
/* skip disabled ports */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"
\n
Statistics for port %u ------------------------------"
"
\n
Packets sent: %24"
PRIu64
"
\n
Packets received: %20"
PRIu64
"
\n
Packets dropped: %21"
PRIu64
,
portid
,
port_statistics
[
portid
].
tx
,
port_statistics
[
portid
].
rx
,
port_statistics
[
portid
].
dropped
);
total_packets_dropped
+=
port_statistics
[
portid
].
dropped
;
total_packets_tx
+=
port_statistics
[
portid
].
tx
;
total_packets_rx
+=
port_statistics
[
portid
].
rx
;
}
printf
(
"
\n
Aggregate statistics ==============================="
"
\n
Total packets sent: %18"
PRIu64
"
\n
Total packets received: %14"
PRIu64
"
\n
Total packets dropped: %15"
PRIu64
,
total_packets_tx
,
total_packets_rx
,
total_packets_dropped
);
printf
(
"
\n
====================================================
\n
"
);
fflush
(
stdout
);
}
static
void
l2fwd_mac_updating
(
struct
rte_mbuf
*
m
,
unsigned
dest_portid
)
{
struct
rte_ether_hdr
*
eth
;
void
*
tmp
;
eth
=
rte_pktmbuf_mtod
(
m
,
struct
rte_ether_hdr
*
);
/* 02:00:00:00:00:xx */
/* 0c:42:a1:df:ac:40 41 */
tmp
=
&
eth
->
d_addr
.
addr_bytes
[
0
];
// @rinku
//*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);
*
((
uint64_t
*
)
tmp
)
=
0x40acdfa1420c
+
((
uint64_t
)
dest_portid
<<
56
);
/* src addr */
rte_ether_addr_copy
(
&
l2fwd_ports_eth_addr
[
dest_portid
],
&
eth
->
s_addr
);
// @rinku
struct
rte_ipv4_hdr
*
ipv4_hdr
;
if
(
RTE_ETH_IS_IPV4_HDR
(
m
->
packet_type
))
{
ipv4_hdr
=
rte_pktmbuf_mtod_offset
(
m
,
struct
rte_ipv4_hdr
*
,
sizeof
(
struct
rte_ether_hdr
));
uint32_t
tmp_dst
;
tmp_dst
=
ipv4_hdr
->
src_addr
;
ipv4_hdr
->
src_addr
=
ipv4_hdr
->
dst_addr
;
ipv4_hdr
->
dst_addr
=
tmp_dst
;
}
// @rinku
struct
rte_udp_hdr
*
udp
;
if
(
ipv4_hdr
->
next_proto_id
==
IPPROTO_UDP
)
{
udp
=
(
struct
rte_udp_hdr
*
)((
unsigned
char
*
)
ipv4_hdr
+
sizeof
(
struct
rte_ipv4_hdr
));
uint16_t
port_dst
=
udp
->
dst_port
;
udp
->
dst_port
=
udp
->
src_port
;
udp
->
src_port
=
port_dst
;
}
}
static
void
l2fwd_simple_forward
(
struct
rte_mbuf
*
m
,
unsigned
portid
)
{
unsigned
dst_port
;
int
sent
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
dst_port
=
l2fwd_dst_ports
[
portid
];
//printf("DEST PORT = %u", dst_port);
//@rinku
/*if (dst_port == 0)
dst_port = 1;
else if (dst_port == 1)
dst_port = 0;*/
if
(
mac_updating
)
l2fwd_mac_updating
(
m
,
dst_port
);
buffer
=
tx_buffer
[
dst_port
];
sent
=
rte_eth_tx_buffer
(
dst_port
,
0
,
buffer
,
m
);
if
(
sent
)
port_statistics
[
dst_port
].
tx
+=
sent
;
}
/* main processing loop */
static
void
l2fwd_main_loop
(
void
)
{
struct
rte_mbuf
*
pkts_burst
[
MAX_PKT_BURST
];
struct
rte_mbuf
*
m
;
int
sent
;
unsigned
lcore_id
;
uint64_t
prev_tsc
,
diff_tsc
,
cur_tsc
,
timer_tsc
;
unsigned
i
,
j
,
portid
,
nb_rx
;
struct
lcore_queue_conf
*
qconf
;
const
uint64_t
drain_tsc
=
(
rte_get_tsc_hz
()
+
US_PER_S
-
1
)
/
US_PER_S
*
BURST_TX_DRAIN_US
;
struct
rte_eth_dev_tx_buffer
*
buffer
;
prev_tsc
=
0
;
timer_tsc
=
0
;
lcore_id
=
rte_lcore_id
();
qconf
=
&
lcore_queue_conf
[
lcore_id
];
if
(
qconf
->
n_rx_port
==
0
)
{
RTE_LOG
(
INFO
,
L2FWD
,
"lcore %u has nothing to do
\n
"
,
lcore_id
);
return
;
}
RTE_LOG
(
INFO
,
L2FWD
,
"entering main loop on lcore %u
\n
"
,
lcore_id
);
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
RTE_LOG
(
INFO
,
L2FWD
,
" -- lcoreid=%u portid=%u
\n
"
,
lcore_id
,
portid
);
}
while
(
!
force_quit
)
{
cur_tsc
=
rte_rdtsc
();
/*
* TX burst queue drain
*/
diff_tsc
=
cur_tsc
-
prev_tsc
;
if
(
unlikely
(
diff_tsc
>
drain_tsc
))
{
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
l2fwd_dst_ports
[
qconf
->
rx_port_list
[
i
]];
buffer
=
tx_buffer
[
portid
];
sent
=
rte_eth_tx_buffer_flush
(
portid
,
0
,
buffer
);
if
(
sent
)
port_statistics
[
portid
].
tx
+=
sent
;
}
/* if timer is enabled */
if
(
timer_period
>
0
)
{
/* advance the timer */
timer_tsc
+=
diff_tsc
;
/* if timer has reached its timeout */
if
(
unlikely
(
timer_tsc
>=
timer_period
))
{
/* do this only on main core */
if
(
lcore_id
==
rte_get_main_lcore
())
{
print_stats
();
/* reset the timer */
timer_tsc
=
0
;
}
}
}
prev_tsc
=
cur_tsc
;
}
/*
* Read packet from RX queues
*/
for
(
i
=
0
;
i
<
qconf
->
n_rx_port
;
i
++
)
{
portid
=
qconf
->
rx_port_list
[
i
];
nb_rx
=
rte_eth_rx_burst
(
portid
,
0
,
pkts_burst
,
MAX_PKT_BURST
);
port_statistics
[
portid
].
rx
+=
nb_rx
;
for
(
j
=
0
;
j
<
nb_rx
;
j
++
)
{
m
=
pkts_burst
[
j
];
rte_prefetch0
(
rte_pktmbuf_mtod
(
m
,
void
*
));
l2fwd_simple_forward
(
m
,
portid
);
}
}
}
}
static
int
l2fwd_launch_one_lcore
(
__rte_unused
void
*
dummy
)
{
l2fwd_main_loop
();
return
0
;
}
/* display usage */
static
void
l2fwd_usage
(
const
char
*
prgname
)
{
printf
(
"%s [EAL options] -- -p PORTMASK [-q NQ]
\n
"
" -p PORTMASK: hexadecimal bitmask of ports to configure
\n
"
" -q NQ: number of queue (=ports) per lcore (default is 1)
\n
"
" -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)
\n
"
" --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)
\n
"
" When enabled:
\n
"
" - The source MAC address is replaced by the TX port MAC address
\n
"
" - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID
\n
"
" --portmap: Configure forwarding port pair mapping
\n
"
" Default: alternate port pairs
\n\n
"
,
prgname
);
}
static
int
l2fwd_parse_portmask
(
const
char
*
portmask
)
{
char
*
end
=
NULL
;
unsigned
long
pm
;
/* parse hexadecimal string */
pm
=
strtoul
(
portmask
,
&
end
,
16
);
if
((
portmask
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
return
pm
;
}
static
int
l2fwd_parse_port_pair_config
(
const
char
*
q_arg
)
{
enum
fieldnames
{
FLD_PORT1
=
0
,
FLD_PORT2
,
_NUM_FLD
};
unsigned
long
int_fld
[
_NUM_FLD
];
const
char
*
p
,
*
p0
=
q_arg
;
char
*
str_fld
[
_NUM_FLD
];
unsigned
int
size
;
char
s
[
256
];
char
*
end
;
int
i
;
nb_port_pair_params
=
0
;
while
((
p
=
strchr
(
p0
,
'('
))
!=
NULL
)
{
++
p
;
p0
=
strchr
(
p
,
')'
);
if
(
p0
==
NULL
)
return
-
1
;
size
=
p0
-
p
;
if
(
size
>=
sizeof
(
s
))
return
-
1
;
memcpy
(
s
,
p
,
size
);
s
[
size
]
=
'\0'
;
if
(
rte_strsplit
(
s
,
sizeof
(
s
),
str_fld
,
_NUM_FLD
,
','
)
!=
_NUM_FLD
)
return
-
1
;
for
(
i
=
0
;
i
<
_NUM_FLD
;
i
++
)
{
errno
=
0
;
int_fld
[
i
]
=
strtoul
(
str_fld
[
i
],
&
end
,
0
);
if
(
errno
!=
0
||
end
==
str_fld
[
i
]
||
int_fld
[
i
]
>=
RTE_MAX_ETHPORTS
)
return
-
1
;
}
if
(
nb_port_pair_params
>=
RTE_MAX_ETHPORTS
/
2
)
{
printf
(
"exceeded max number of port pair params: %hu
\n
"
,
nb_port_pair_params
);
return
-
1
;
}
port_pair_params_array
[
nb_port_pair_params
].
port
[
0
]
=
(
uint16_t
)
int_fld
[
FLD_PORT1
];
port_pair_params_array
[
nb_port_pair_params
].
port
[
1
]
=
(
uint16_t
)
int_fld
[
FLD_PORT2
];
++
nb_port_pair_params
;
}
port_pair_params
=
port_pair_params_array
;
return
0
;
}
static
unsigned
int
l2fwd_parse_nqueue
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
unsigned
long
n
;
/* parse hexadecimal string */
n
=
strtoul
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
0
;
if
(
n
==
0
)
return
0
;
if
(
n
>=
MAX_RX_QUEUE_PER_LCORE
)
return
0
;
return
n
;
}
static
int
l2fwd_parse_timer_period
(
const
char
*
q_arg
)
{
char
*
end
=
NULL
;
int
n
;
/* parse number string */
n
=
strtol
(
q_arg
,
&
end
,
10
);
if
((
q_arg
[
0
]
==
'\0'
)
||
(
end
==
NULL
)
||
(
*
end
!=
'\0'
))
return
-
1
;
if
(
n
>=
MAX_TIMER_PERIOD
)
return
-
1
;
return
n
;
}
static
const
char
short_options
[]
=
"p:"
/* portmask */
"q:"
/* number of queues */
"T:"
/* timer period */
;
#define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
#define CMD_LINE_OPT_PORTMAP_CONFIG "portmap"
enum
{
/* long options mapped to a short option */
/* first long only option value must be >= 256, so that we won't
* conflict with short options */
CMD_LINE_OPT_MIN_NUM
=
256
,
CMD_LINE_OPT_PORTMAP_NUM
,
};
static
const
struct
option
lgopts
[]
=
{
{
CMD_LINE_OPT_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
1
},
{
CMD_LINE_OPT_NO_MAC_UPDATING
,
no_argument
,
&
mac_updating
,
0
},
{
CMD_LINE_OPT_PORTMAP_CONFIG
,
1
,
0
,
CMD_LINE_OPT_PORTMAP_NUM
},
{
NULL
,
0
,
0
,
0
}
};
/* Parse the argument given in the command line of the application */
static
int
l2fwd_parse_args
(
int
argc
,
char
**
argv
)
{
int
opt
,
ret
,
timer_secs
;
char
**
argvopt
;
int
option_index
;
char
*
prgname
=
argv
[
0
];
argvopt
=
argv
;
port_pair_params
=
NULL
;
while
((
opt
=
getopt_long
(
argc
,
argvopt
,
short_options
,
lgopts
,
&
option_index
))
!=
EOF
)
{
switch
(
opt
)
{
/* portmask */
case
'p'
:
l2fwd_enabled_port_mask
=
l2fwd_parse_portmask
(
optarg
);
if
(
l2fwd_enabled_port_mask
==
0
)
{
printf
(
"invalid portmask
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* nqueue */
case
'q'
:
l2fwd_rx_queue_per_lcore
=
l2fwd_parse_nqueue
(
optarg
);
if
(
l2fwd_rx_queue_per_lcore
==
0
)
{
printf
(
"invalid queue number
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
/* timer period */
case
'T'
:
timer_secs
=
l2fwd_parse_timer_period
(
optarg
);
if
(
timer_secs
<
0
)
{
printf
(
"invalid timer period
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
timer_period
=
timer_secs
;
break
;
/* long options */
case
CMD_LINE_OPT_PORTMAP_NUM
:
ret
=
l2fwd_parse_port_pair_config
(
optarg
);
if
(
ret
)
{
fprintf
(
stderr
,
"Invalid config
\n
"
);
l2fwd_usage
(
prgname
);
return
-
1
;
}
break
;
default:
l2fwd_usage
(
prgname
);
return
-
1
;
}
}
if
(
optind
>=
0
)
argv
[
optind
-
1
]
=
prgname
;
ret
=
optind
-
1
;
optind
=
1
;
/* reset getopt lib */
return
ret
;
}
/*
* Check port pair config with enabled port mask,
* and for valid port pair combinations.
*/
static
int
check_port_pair_config
(
void
)
{
uint32_t
port_pair_config_mask
=
0
;
uint32_t
port_pair_mask
=
0
;
uint16_t
index
,
i
,
portid
;
for
(
index
=
0
;
index
<
nb_port_pair_params
;
index
++
)
{
port_pair_mask
=
0
;
for
(
i
=
0
;
i
<
NUM_PORTS
;
i
++
)
{
portid
=
port_pair_params
[
index
].
port
[
i
];
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"port %u is not enabled in port mask
\n
"
,
portid
);
return
-
1
;
}
if
(
!
rte_eth_dev_is_valid_port
(
portid
))
{
printf
(
"port %u is not present on the board
\n
"
,
portid
);
return
-
1
;
}
port_pair_mask
|=
1
<<
portid
;
}
if
(
port_pair_config_mask
&
port_pair_mask
)
{
printf
(
"port %u is used in other port pairs
\n
"
,
portid
);
return
-
1
;
}
port_pair_config_mask
|=
port_pair_mask
;
}
l2fwd_enabled_port_mask
&=
port_pair_config_mask
;
return
0
;
}
/* Check the link status of all ports in up to 9s, and print them finally */
static
void
check_all_ports_link_status
(
uint32_t
port_mask
)
{
#define CHECK_INTERVAL 100
/* 100ms */
#define MAX_CHECK_TIME 90
/* 9s (90 * 100ms) in total */
uint16_t
portid
;
uint8_t
count
,
all_ports_up
,
print_flag
=
0
;
struct
rte_eth_link
link
;
int
ret
;
char
link_status_text
[
RTE_ETH_LINK_MAX_STR_LEN
];
printf
(
"
\n
Checking link status"
);
fflush
(
stdout
);
for
(
count
=
0
;
count
<=
MAX_CHECK_TIME
;
count
++
)
{
if
(
force_quit
)
return
;
all_ports_up
=
1
;
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
(
force_quit
)
return
;
if
((
port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
memset
(
&
link
,
0
,
sizeof
(
link
));
ret
=
rte_eth_link_get_nowait
(
portid
,
&
link
);
if
(
ret
<
0
)
{
all_ports_up
=
0
;
if
(
print_flag
==
1
)
printf
(
"Port %u link get failed: %s
\n
"
,
portid
,
rte_strerror
(
-
ret
));
continue
;
}
/* print link status if flag set */
if
(
print_flag
==
1
)
{
rte_eth_link_to_str
(
link_status_text
,
sizeof
(
link_status_text
),
&
link
);
printf
(
"Port %d %s
\n
"
,
portid
,
link_status_text
);
continue
;
}
/* clear all_ports_up flag if any link down */
if
(
link
.
link_status
==
ETH_LINK_DOWN
)
{
all_ports_up
=
0
;
break
;
}
}
/* after finally printing all link status, get out */
if
(
print_flag
==
1
)
break
;
if
(
all_ports_up
==
0
)
{
printf
(
"."
);
fflush
(
stdout
);
rte_delay_ms
(
CHECK_INTERVAL
);
}
/* set the print_flag if all ports up or timeout */
if
(
all_ports_up
==
1
||
count
==
(
MAX_CHECK_TIME
-
1
))
{
print_flag
=
1
;
printf
(
"done
\n
"
);
}
}
}
static
void
signal_handler
(
int
signum
)
{
if
(
signum
==
SIGINT
||
signum
==
SIGTERM
)
{
printf
(
"
\n\n
Signal %d received, preparing to exit...
\n
"
,
signum
);
force_quit
=
true
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
struct
lcore_queue_conf
*
qconf
;
int
ret
;
uint16_t
nb_ports
;
uint16_t
nb_ports_available
=
0
;
uint16_t
portid
,
last_port
;
unsigned
lcore_id
,
rx_lcore_id
;
unsigned
nb_ports_in_mask
=
0
;
unsigned
int
nb_lcores
=
0
;
unsigned
int
nb_mbufs
;
/* init EAL */
ret
=
rte_eal_init
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid EAL arguments
\n
"
);
argc
-=
ret
;
argv
+=
ret
;
force_quit
=
false
;
signal
(
SIGINT
,
signal_handler
);
signal
(
SIGTERM
,
signal_handler
);
/* parse application arguments (after the EAL ones) */
ret
=
l2fwd_parse_args
(
argc
,
argv
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid L2FWD arguments
\n
"
);
printf
(
"MAC updating %s
\n
"
,
mac_updating
?
"enabled"
:
"disabled"
);
/* convert to number of cycles */
timer_period
*=
rte_get_timer_hz
();
nb_ports
=
rte_eth_dev_count_avail
();
if
(
nb_ports
==
0
)
rte_exit
(
EXIT_FAILURE
,
"No Ethernet ports - bye
\n
"
);
if
(
port_pair_params
!=
NULL
)
{
if
(
check_port_pair_config
()
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Invalid port pair config
\n
"
);
}
/* check port mask to possible port mask */
if
(
l2fwd_enabled_port_mask
&
~
((
1
<<
nb_ports
)
-
1
))
rte_exit
(
EXIT_FAILURE
,
"Invalid portmask; possible (0x%x)
\n
"
,
(
1
<<
nb_ports
)
-
1
);
/* reset l2fwd_dst_ports */
for
(
portid
=
0
;
portid
<
RTE_MAX_ETHPORTS
;
portid
++
)
l2fwd_dst_ports
[
portid
]
=
0
;
last_port
=
0
;
/* populate destination port details */
if
(
port_pair_params
!=
NULL
)
{
uint16_t
idx
,
p
;
for
(
idx
=
0
;
idx
<
(
nb_port_pair_params
<<
1
);
idx
++
)
{
p
=
idx
&
1
;
portid
=
port_pair_params
[
idx
>>
1
].
port
[
p
];
l2fwd_dst_ports
[
portid
]
=
port_pair_params
[
idx
>>
1
].
port
[
p
^
1
];
}
}
else
{
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
if
(
nb_ports_in_mask
%
2
)
{
l2fwd_dst_ports
[
portid
]
=
last_port
;
l2fwd_dst_ports
[
last_port
]
=
portid
;
}
else
{
last_port
=
portid
;
}
nb_ports_in_mask
++
;
}
if
(
nb_ports_in_mask
%
2
)
{
printf
(
"Notice: odd number of ports in portmask.
\n
"
);
l2fwd_dst_ports
[
last_port
]
=
last_port
;
}
}
rx_lcore_id
=
0
;
qconf
=
NULL
;
/* Initialize the port/queue configuration of each logical core */
RTE_ETH_FOREACH_DEV
(
portid
)
{
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
/* get the lcore_id for this port */
while
(
rte_lcore_is_enabled
(
rx_lcore_id
)
==
0
||
lcore_queue_conf
[
rx_lcore_id
].
n_rx_port
==
l2fwd_rx_queue_per_lcore
)
{
rx_lcore_id
++
;
if
(
rx_lcore_id
>=
RTE_MAX_LCORE
)
rte_exit
(
EXIT_FAILURE
,
"Not enough cores
\n
"
);
}
if
(
qconf
!=
&
lcore_queue_conf
[
rx_lcore_id
])
{
/* Assigned a new logical core in the loop above. */
qconf
=
&
lcore_queue_conf
[
rx_lcore_id
];
nb_lcores
++
;
}
qconf
->
rx_port_list
[
qconf
->
n_rx_port
]
=
portid
;
qconf
->
n_rx_port
++
;
printf
(
"Lcore %u: RX port %u TX port %u
\n
"
,
rx_lcore_id
,
portid
,
l2fwd_dst_ports
[
portid
]);
}
nb_mbufs
=
RTE_MAX
(
nb_ports
*
(
nb_rxd
+
nb_txd
+
MAX_PKT_BURST
+
nb_lcores
*
MEMPOOL_CACHE_SIZE
),
8192U
);
/* create the mbuf pool */
l2fwd_pktmbuf_pool
=
rte_pktmbuf_pool_create
(
"mbuf_pool"
,
nb_mbufs
,
MEMPOOL_CACHE_SIZE
,
0
,
RTE_MBUF_DEFAULT_BUF_SIZE
,
rte_socket_id
());
if
(
l2fwd_pktmbuf_pool
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot init mbuf pool
\n
"
);
/* Initialise each port */
RTE_ETH_FOREACH_DEV
(
portid
)
{
struct
rte_eth_rxconf
rxq_conf
;
struct
rte_eth_txconf
txq_conf
;
struct
rte_eth_conf
local_port_conf
=
port_conf
;
struct
rte_eth_dev_info
dev_info
;
/* skip ports that are not enabled */
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
{
printf
(
"Skipping disabled port %u
\n
"
,
portid
);
continue
;
}
nb_ports_available
++
;
/* init port */
printf
(
"Initializing port %u... "
,
portid
);
fflush
(
stdout
);
ret
=
rte_eth_dev_info_get
(
portid
,
&
dev_info
);
if
(
ret
!=
0
)
rte_exit
(
EXIT_FAILURE
,
"Error during getting device (port %u) info: %s
\n
"
,
portid
,
strerror
(
-
ret
));
if
(
dev_info
.
tx_offload_capa
&
DEV_TX_OFFLOAD_MBUF_FAST_FREE
)
local_port_conf
.
txmode
.
offloads
|=
DEV_TX_OFFLOAD_MBUF_FAST_FREE
;
ret
=
rte_eth_dev_configure
(
portid
,
1
,
1
,
&
local_port_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot configure device: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_dev_adjust_nb_rx_tx_desc
(
portid
,
&
nb_rxd
,
&
nb_txd
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot adjust number of descriptors: err=%d, port=%u
\n
"
,
ret
,
portid
);
ret
=
rte_eth_macaddr_get
(
portid
,
&
l2fwd_ports_eth_addr
[
portid
]);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot get MAC address: err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one RX queue */
fflush
(
stdout
);
rxq_conf
=
dev_info
.
default_rxconf
;
rxq_conf
.
offloads
=
local_port_conf
.
rxmode
.
offloads
;
ret
=
rte_eth_rx_queue_setup
(
portid
,
0
,
nb_rxd
,
rte_eth_dev_socket_id
(
portid
),
&
rxq_conf
,
l2fwd_pktmbuf_pool
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_rx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* init one TX queue on each port */
fflush
(
stdout
);
txq_conf
=
dev_info
.
default_txconf
;
txq_conf
.
offloads
=
local_port_conf
.
txmode
.
offloads
;
ret
=
rte_eth_tx_queue_setup
(
portid
,
0
,
nb_txd
,
rte_eth_dev_socket_id
(
portid
),
&
txq_conf
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_tx_queue_setup:err=%d, port=%u
\n
"
,
ret
,
portid
);
/* Initialize TX buffers */
tx_buffer
[
portid
]
=
rte_zmalloc_socket
(
"tx_buffer"
,
RTE_ETH_TX_BUFFER_SIZE
(
MAX_PKT_BURST
),
0
,
rte_eth_dev_socket_id
(
portid
));
if
(
tx_buffer
[
portid
]
==
NULL
)
rte_exit
(
EXIT_FAILURE
,
"Cannot allocate buffer for tx on port %u
\n
"
,
portid
);
rte_eth_tx_buffer_init
(
tx_buffer
[
portid
],
MAX_PKT_BURST
);
ret
=
rte_eth_tx_buffer_set_err_callback
(
tx_buffer
[
portid
],
rte_eth_tx_buffer_count_callback
,
&
port_statistics
[
portid
].
dropped
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"Cannot set error callback for tx buffer on port %u
\n
"
,
portid
);
ret
=
rte_eth_dev_set_ptypes
(
portid
,
RTE_PTYPE_UNKNOWN
,
NULL
,
0
);
if
(
ret
<
0
)
printf
(
"Port %u, Failed to disable Ptype parsing
\n
"
,
portid
);
/* Start device */
ret
=
rte_eth_dev_start
(
portid
);
if
(
ret
<
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_dev_start:err=%d, port=%u
\n
"
,
ret
,
portid
);
printf
(
"done:
\n
"
);
ret
=
rte_eth_promiscuous_enable
(
portid
);
if
(
ret
!=
0
)
rte_exit
(
EXIT_FAILURE
,
"rte_eth_promiscuous_enable:err=%s, port=%u
\n
"
,
rte_strerror
(
-
ret
),
portid
);
printf
(
"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X
\n\n
"
,
portid
,
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
0
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
1
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
2
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
3
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
4
],
l2fwd_ports_eth_addr
[
portid
].
addr_bytes
[
5
]);
/* initialize port stats */
memset
(
&
port_statistics
,
0
,
sizeof
(
port_statistics
));
}
if
(
!
nb_ports_available
)
{
rte_exit
(
EXIT_FAILURE
,
"All available ports are disabled. Please set portmask.
\n
"
);
}
check_all_ports_link_status
(
l2fwd_enabled_port_mask
);
ret
=
0
;
/* launch per-lcore init on every lcore */
rte_eal_mp_remote_launch
(
l2fwd_launch_one_lcore
,
NULL
,
CALL_MAIN
);
RTE_LCORE_FOREACH_WORKER
(
lcore_id
)
{
if
(
rte_eal_wait_lcore
(
lcore_id
)
<
0
)
{
ret
=
-
1
;
break
;
}
}
RTE_ETH_FOREACH_DEV
(
portid
)
{
if
((
l2fwd_enabled_port_mask
&
(
1
<<
portid
))
==
0
)
continue
;
printf
(
"Closing port %d..."
,
portid
);
ret
=
rte_eth_dev_stop
(
portid
);
if
(
ret
!=
0
)
printf
(
"rte_eth_dev_stop: err=%d, port=%d
\n
"
,
ret
,
portid
);
rte_eth_dev_close
(
portid
);
printf
(
" Done
\n
"
);
}
printf
(
"Bye...
\n
"
);
return
ret
;
}
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/dpdk-server/l2fwd/meson.build
0 → 100644
View file @
f7053183
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
# meson file, for building this example as part of a main DPDK build.
#
# To build this example as a standalone application with an already-installed
# DPDK instance, use 'make'
# Enable experimental API flag as l2fwd uses rte_ethdev_set_ptype API
allow_experimental_apis = true
sources = files(
'main.c'
)
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/client
0 → 100755
View file @
f7053183
File added
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/client.cpp
0 → 100755
View file @
f7053183
#include "client.h"
#define NO_EPOCH 6
#define INST_ARR_LEN 300
#define INST_PERIOD 10 // period in secs
struct
_threadArgs
{
int
threadId
;
int
num_threads
;
};
struct
_srcPortArgs
{
int
startingPort
;
int
endingPort
;
int
numPorts
;
};
int
flowWeight
;
// Number of messages send for encryption/decryption per connection
vector
<
unsigned
long
long
>
num_req_per_thread_P
,
num_req_per_thread_G
,
num_req_per_thread
;
vector
<
unsigned
long
long
>
response_time_P
,
response_time_G
,
response_time
;
struct
timeval
start
;
// Simulation start time
time_t
endTime
;
// Simulation end time
long
mtime
,
useconds
,
seconds
;
//For resp time calc
double
num_ue_inst
[
INST_ARR_LEN
]
=
{
0
};
// Enough to store 50 min data if captured after every 10 sec
double
resp_time_inst
[
INST_ARR_LEN
]
=
{
0
};
// Enough to store 50 min data if captured after every 10 sec
int
instIndex
=
0
;
// Index to remember number of entries in instr arrays
time_t
inst_endTime
;
//End time of instrumenting current period (10sec)
unsigned
long
long
prev_tpt
=
0
;
//To remember tpt till previous period
unsigned
long
long
prev_lat
=
0
;
//To remember lat till previous period
/// DYNAMIC LOAD GENERATOR VARIABLES START HERE ///
std
::
mutex
traffic_mtx
;
std
::
mutex
inst_mtx
;
std
::
mutex
lat_mtx
;
int
traffic_shape_size
=
NO_EPOCH
;
//0---5:95
//1---10_80
//2---18_82
//3---25_75
//4---50_50
//5---66_34
//6---75_25
//7---100_1
//traffic_shape[][] = {{time,mix_num}}
int
traffic_shape
[
10
][
2
]
=
{{
5
,
1
},{
5
,
0
},{
5
,
7
},{
6
,
2
},{
5
,
0
},{
5
,
5
},{
5
,
4
},{
6
,
1
}};
//int traffic_shape[5][2] = {{5,0},{5,6},{5,0},{6,6}};
//int traffic_shape[5][2] = {{2,0},{2,1},{2,2},{2,3}};
int
curr_mix_index
=
0
;
bool
dynLoad
=
true
;
bool
instrumentTptLat
=
true
;
//Instrument num_ue and response_time every 10 sec
int
mix_num
=
0
;
//choose the traffix mix from above traffic_options -> {0,1,2}
time_t
mix_endTime
;
//End time of current traffic mix
float
tpt
[
NO_EPOCH
]
=
{
0
};
float
lat
[
NO_EPOCH
]
=
{
0
};
unsigned
long
long
num_req_per_epoch
[
NO_EPOCH
]
=
{
0
};
unsigned
long
long
response_time_per_epoch
[
NO_EPOCH
]
=
{
0
};
/// DYNAMIC LOAD GENERATOR VARIABLES END HERE ///
bool
putFlag
=
true
;
//int put_percent = 100; //out of 1000 eg. 100 = 10%
//nPut & nGet are used to generate varied load as put:get
//0---1:20---5% put
//1---1:10---10% put
//2---1:5---18%
//3---1:3---25%
//4---1:1---50%
//5---2:1---66%
//6---3:1---75%
//7---1:0---100%
int
nPut
=
1
;
int
nGet
=
20
;
// Thread function for each simulated UE
void
*
multithreading_func
(
void
*
arg
){
struct
_threadArgs
*
args
=
(
struct
_threadArgs
*
)
arg
;
int
threadId
=
args
->
threadId
;
int
maxThreads
=
args
->
num_threads
;
Network
user
(
threadId
+
1
);
pthread_setcancelstate
(
PTHREAD_CANCEL_ENABLE
,
NULL
);
pthread_setcanceltype
(
PTHREAD_CANCEL_ASYNCHRONOUS
,
NULL
);
time_t
curTime
;
time
(
&
curTime
);
struct
timeval
start1
,
end1
;
//Used to find time between request send n response received // response time metrics
int
key
=
1
;
// key is used for the key
while
(
curTime
<
endTime
){
do
{
UserEquipment
ue
(
threadId
+
1
);
gettimeofday
(
&
start
,
NULL
);
int
step
=
1
;
//threadId * flowWeight;
/*if((putFlag) && (threadId==0)){
for (int k=0; k<flowWeight; k++){
gettimeofday(&start1, NULL);
putG(user,ue,k+step,k+1);
//usleep(1);
num_req_per_thread_P[threadId]++;
num_req_per_thread[threadId]++;
//////PRINT CONN RESP TIME TO ARRAY////
gettimeofday(&end1, NULL);
seconds = end1.tv_sec - start1.tv_sec;
useconds = end1.tv_usec - start1.tv_usec;
mtime = ((seconds) * 1000000 + useconds);
response_time_P[threadId] += mtime;
response_time[threadId] += mtime;
}
//sleep(1);
putFlag=false;
}*/
//int step = threadId * flowWeight;
//cout<<"Step= " <<step<<endl;
int
max
=
(
threadId
+
1
)
*
1000
;
key
=
threadId
*
1000
;
//for (int i=0; i<flowWeight; i++){
//for (int k=0; k < nPut; k++){
for
(
int
k
=
0
;
k
<
10000
;
k
++
){
//PUT CODE
gettimeofday
(
&
start1
,
NULL
);
//putG(user,ue,key+step,key+1);
putG
(
user
,
ue
,
key
,
key
+
1
);
//usleep(1);
//sleep(60);
key
=
(
key
+
1
)
%
max
;
num_req_per_thread_P
[
threadId
]
++
;
num_req_per_thread
[
threadId
]
++
;
//////PRINT CONN RESP TIME TO ARRAY////
gettimeofday
(
&
end1
,
NULL
);
seconds
=
end1
.
tv_sec
-
start1
.
tv_sec
;
useconds
=
end1
.
tv_usec
-
start1
.
tv_usec
;
mtime
=
((
seconds
)
*
1000000
+
useconds
);
response_time_P
[
threadId
]
+=
mtime
;
response_time
[
threadId
]
+=
mtime
;
}
/*for (int k=0; k < nGet; k++){
//GET CODE
gettimeofday(&start1, NULL);
get(user,ue,key+step);
//usleep(1);
num_req_per_thread_G[threadId]++;
num_req_per_thread[threadId]++;
//////PRINT CONN RESP TIME TO ARRAY////
gettimeofday(&end1, NULL);
seconds = end1.tv_sec - start1.tv_sec;
useconds = end1.tv_usec - start1.tv_usec;
mtime = ((seconds) * 1000000 + useconds);
response_time_G[threadId] += mtime;
response_time[threadId] += mtime;
}*/
/*if (key < flowWeight){ //i is used for key
key++;
} else
{ key = 0;
}*/
//usleep(1000);
//Terminate the connection
gettimeofday
(
&
start1
,
NULL
);
//////PRINT CONN RESP TIME TO ARRAY////
gettimeofday
(
&
end1
,
NULL
);
seconds
=
end1
.
tv_sec
-
start1
.
tv_sec
;
useconds
=
end1
.
tv_usec
-
start1
.
tv_usec
;
mtime
=
((
seconds
)
*
1000000
+
useconds
);
time
(
&
curTime
);
////// DYNAMIC LOAD GENERATION CODE STARTS HERE /////////////////////////////////////////////////////////
if
(
dynLoad
){
traffic_mtx
.
lock
();
if
(
curTime
>=
mix_endTime
)
{
lat_mtx
.
lock
();
for
(
int
i
=
0
;
i
<
maxThreads
;
i
++
){
num_req_per_epoch
[
curr_mix_index
]
=
num_req_per_epoch
[
curr_mix_index
]
+
num_req_per_thread
[
i
];
response_time_per_epoch
[
curr_mix_index
]
=
response_time_per_epoch
[
curr_mix_index
]
+
response_time
[
i
];
}
lat_mtx
.
unlock
();
if
(
curr_mix_index
>
0
){
int
i
=
curr_mix_index
;
while
(
i
>
0
)
{
num_req_per_epoch
[
curr_mix_index
]
=
num_req_per_epoch
[
curr_mix_index
]
-
num_req_per_epoch
[
i
-
1
];
response_time_per_epoch
[
curr_mix_index
]
=
response_time_per_epoch
[
curr_mix_index
]
-
response_time_per_epoch
[
i
-
1
];
i
--
;
}
}
float
tmp_tpt
=
(
num_req_per_epoch
[
curr_mix_index
]
*
1.0
)
/
(
traffic_shape
[
curr_mix_index
][
0
]
*
60
);
float
tmp_lat
=
(
response_time_per_epoch
[
curr_mix_index
]
*
0.001
)
/
num_req_per_epoch
[
curr_mix_index
];
tpt
[
curr_mix_index
]
=
tmp_tpt
;
lat
[
curr_mix_index
]
=
tmp_lat
;
if
(
curr_mix_index
<
traffic_shape_size
){
curr_mix_index
++
;
}
mix_num
=
traffic_shape
[
curr_mix_index
][
1
];
setMix
(
mix_num
);
int
tmp1
=
traffic_shape
[
curr_mix_index
][
0
]
*
60
;
mix_endTime
=
curTime
+
(
int
)
tmp1
;
cout
<<
"mix="
<<
mix_num
<<
endl
;
}
traffic_mtx
.
unlock
();
}
////// DYNAMIC LOAD GENERATION CODE ENDS HERE /////////////////////////////////////////////////////////
////// INSTRUMENTATION CODE STARTS HERE /////////////////////////////////////////////////////////
if
(
instrumentTptLat
){
inst_mtx
.
lock
();
time
(
&
curTime
);
if
(
curTime
>=
inst_endTime
)
{
//cout<<"start time="<<curTime<<endl;
lat_mtx
.
lock
();
//num_ue_inst[instIndex] = attNo + detNo + sreqNo;
for
(
int
i
=
0
;
i
<
maxThreads
;
i
++
){
num_ue_inst
[
instIndex
]
=
num_ue_inst
[
instIndex
]
+
num_req_per_thread
[
i
];
resp_time_inst
[
instIndex
]
=
resp_time_inst
[
instIndex
]
+
response_time
[
i
];
}
lat_mtx
.
unlock
();
float
prev_t
=
num_ue_inst
[
instIndex
];
float
prev_l
=
resp_time_inst
[
instIndex
];
num_ue_inst
[
instIndex
]
=
num_ue_inst
[
instIndex
]
-
prev_tpt
;
//Get current period val
resp_time_inst
[
instIndex
]
=
resp_time_inst
[
instIndex
]
-
prev_lat
;
resp_time_inst
[
instIndex
]
=
(
resp_time_inst
[
instIndex
]
*
0.001
)
/
num_ue_inst
[
instIndex
];
//Keep it bfor num_ue_inst update coz we need total number and not throughtput
num_ue_inst
[
instIndex
]
=
(
num_ue_inst
[
instIndex
]
*
1.0
)
/
INST_PERIOD
;
prev_tpt
=
prev_t
;
prev_lat
=
prev_l
;
instIndex
++
;
inst_endTime
=
curTime
+
(
int
)
INST_PERIOD
;
}
inst_mtx
.
unlock
();
}
////// INSTRUMENTATION CODE ENDS HERE /////////////////////////////////////////////////////////
}
while
(
curTime
<
endTime
);
//end do-while
}
//end while
free
(
args
);
pthread_exit
(
NULL
);
}
int
main
(
int
argc
,
char
*
args
[]){
long
maxThreads
=
0
;
int
status
;
stringstream
ss
;
string
data
=
""
;
std
::
ofstream
outfile
;
std
::
ofstream
delayfile
;
std
::
ofstream
instfile
;
if
(
argc
!=
4
){
fprintf
(
stderr
,
"Usage: %s <max-threads> <program-run-time(in mins)> <num-msg per connection(thin/fat flow)>
\n
"
,
args
[
0
]);
exit
(
0
);
}
maxThreads
=
atoi
(
args
[
1
]);
if
(
maxThreads
<=
0
){
printf
(
"Number of threads should be greater than 0
\n
"
);
exit
(
0
);
}
double
tmp
;
ss
<<
args
[
2
];
ss
>>
tmp
;
if
(
tmp
<=
0.0
){
printf
(
"Run time of each threads should be greater than 0.0
\n
"
);
exit
(
0
);
}
flowWeight
=
atoi
(
args
[
3
]);
//cout<<flowWeight;
if
(
flowWeight
<
1
){
printf
(
"Connection size should be atleast 1 packet
\n
"
);
exit
(
0
);
}
num_req_per_thread_P
.
resize
(
maxThreads
,
0
);
num_req_per_thread_G
.
resize
(
maxThreads
,
0
);
num_req_per_thread
.
resize
(
maxThreads
,
0
);
response_time_P
.
resize
(
maxThreads
,
0
);
response_time_G
.
resize
(
maxThreads
,
0
);
response_time
.
resize
(
maxThreads
,
0
);
cout
<<
"***************STARTING NOW***************"
<<
endl
;
tmp
=
tmp
*
60
;
time_t
curTime
;
time
(
&
curTime
);
if
(
DO_DEBUG
){
cout
<<
"start time="
<<
curTime
<<
endl
;
}
endTime
=
curTime
+
(
int
)
tmp
;
if
(
DO_DEBUG
){
cout
<<
"end time="
<<
endTime
<<
endl
;
}
int
simulationTime
=
(
int
)
tmp
;
pthread_t
tid
[
maxThreads
];
///////// DYNAMIC LOAD GEN in MAIN STARTS ///////////////
if
(
dynLoad
){
cout
<<
"start time="
<<
curTime
<<
endl
;
int
tmp1
=
traffic_shape
[
curr_mix_index
][
0
]
*
60
;
mix_endTime
=
curTime
+
(
int
)
tmp1
;
mix_num
=
traffic_shape
[
curr_mix_index
][
1
];
setMix
(
mix_num
);
cout
<<
"mix="
<<
mix_num
<<
endl
;
}
///////// DYNAMIC LOAD GEN in MAIN ENDS ///////////////
///// INSTRUMENTATION CODE STARTS /////////
if
(
instrumentTptLat
){
int
tmp2
=
INST_PERIOD
;
inst_endTime
=
curTime
+
(
int
)
tmp2
;
}
///// INSTRUMENTATION CODE ENDS /////////
// Create UE threads
for
(
int
i
=
0
;
i
<
maxThreads
;
i
++
){
struct
_threadArgs
*
args
=
(
struct
_threadArgs
*
)
malloc
(
sizeof
(
struct
_threadArgs
));
args
->
threadId
=
i
;
args
->
num_threads
=
maxThreads
;
status
=
pthread_create
(
&
tid
[
i
],
NULL
,
multithreading_func
,
args
);
report_error
(
status
);
}
// Sleep for the specified simulation time
usleep
(
simulationTime
*
1000000
);
// 1sec
/* Wake up and cancel/join all the UE threads to end simulation */
for
(
int
i
=
0
;
i
<
maxThreads
;
i
++
){
if
(
DO_DEBUG
){
cout
<<
"******* ENDING THREAD - "
<<
i
<<
endl
;
}
pthread_cancel
(
tid
[
i
]);
pthread_join
(
tid
[
i
],
NULL
);
}
if
(
DO_DEBUG
){
cout
<<
"************ENDED!!!************"
<<
endl
;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/* Calculate and display various metrics */
string
s
=
""
;
int
total_G
=
0
;
int
total_P
=
0
;
unsigned
long
long
total_response_time_P
=
0
;
unsigned
long
long
total_response_time_G
=
0
;
unsigned
long
long
total_conn_response_time
=
0
;
double
average_response_time_P
=
0.0
;
double
average_response_time_G
=
0.0
;
double
average_response_time
=
0.0
;
double
throughput
=
0.0
,
throughput_P
=
0.0
,
throughput_G
=
0.0
;
double
percentP
=
0.0
;
time_t
actual_endTime
;
time
(
&
actual_endTime
);
for
(
int
i
=
0
;
i
<
maxThreads
;
i
++
){
total_P
+=
num_req_per_thread_P
[
i
];
total_G
+=
num_req_per_thread_G
[
i
];
total_response_time_P
+=
response_time_P
[
i
];
total_response_time_G
+=
response_time_G
[
i
];
cout
<<
"num_req_per_thread_P["
<<
i
<<
"] "
<<
num_req_per_thread_P
[
i
]
<<
endl
;
cout
<<
"num_req_per_thread_G["
<<
i
<<
"] "
<<
num_req_per_thread_G
[
i
]
<<
endl
;
cout
<<
"put response_time["
<<
i
<<
"] "
<<
((
response_time_P
[
i
]
*
1.0
)
/
num_req_per_thread_P
[
i
])
<<
" us"
<<
endl
;
cout
<<
"get response_time["
<<
i
<<
"] "
<<
((
response_time_G
[
i
]
*
1.0
)
/
num_req_per_thread_G
[
i
])
<<
" us"
<<
endl
;
}
average_response_time_P
=
(
total_response_time_P
*
1.0
)
/
(
total_P
*
1.0
);
average_response_time_G
=
(
total_response_time_G
*
1.0
)
/
(
total_G
*
1.0
);
average_response_time
=
((
total_response_time_P
+
total_response_time_G
)
*
1.0
)
/
((
total_P
+
total_G
)
*
1.0
);
throughput_P
=
((
total_P
)
*
1.0
)
/
(
actual_endTime
-
curTime
);
throughput_G
=
((
total_G
)
*
1.0
)
/
(
actual_endTime
-
curTime
);
throughput
=
((
total_P
+
total_G
)
*
1.0
)
/
(
actual_endTime
-
curTime
);
percentP
=
(
throughput_P
/
throughput
)
*
100
;
cout
<<
"***************************************STATISTICS***************************************"
<<
endl
;
double
averageReqPerThread
=
(((
total_P
+
total_G
)
*
1.0
)
/
maxThreads
);
averageReqPerThread
=
roundf
(
averageReqPerThread
*
100
)
/
100
;
ostringstream
strsR
;
strsR
<<
averageReqPerThread
;
string
avReq
=
strsR
.
str
();
ostringstream
strsC
;
printf
(
"Total Number of Threads=%ld
\n
"
,
maxThreads
);
printf
(
"Total Number of Puts=%d
\n
"
,
total_P
);
printf
(
"Total Number of Gets=%d
\n
"
,
total_G
);
cout
<<
"Average Number of Requests per Thread="
<<
averageReqPerThread
<<
endl
;
printf
(
"Total Execution Time=%ld sec
\n
"
,
(
actual_endTime
-
curTime
));
average_response_time
=
average_response_time
/
1000000.0
;
cout
<<
"Average Request Latency = "
<<
average_response_time
<<
" secs"
<<
endl
;
cout
<<
"Put Throughput="
<<
throughput_P
<<
" requests/sec"
<<
endl
;
cout
<<
"Get Throughput="
<<
throughput_G
<<
" requests/sec"
<<
endl
;
cout
<<
"Total Throughput="
<<
throughput
<<
" requests/sec"
<<
endl
;
cout
<<
"Put Percent="
<<
percentP
<<
endl
;
if
(
instrumentTptLat
)
{
instfile
.
open
(
INST_FILE
,
std
::
ios_base
::
app
);
data
=
""
;
if
(
instfile
.
is_open
()){
//cout<<"inst_index="<<instIndex<<endl;
for
(
int
i
=
0
;
i
<
instIndex
;
i
++
){
float
t
=
num_ue_inst
[
i
];
float
l
=
resp_time_inst
[
i
];
data
.
append
(
to_string
(
t
)).
append
(
COMMA
).
append
(
to_string
(
l
)).
append
(
"
\n
"
);
}
instfile
<<
data
;
instfile
.
close
();
}
}
/* Write the metrics to the statistics file */
if
(
!
fileExists
(
STATISTIC_FILE
)){
data
.
append
(
"#MaxThreads"
).
append
(
COMMA
);
data
.
append
(
"FlowWeight"
).
append
(
COMMA
).
append
(
"ExecutionTime"
).
append
(
COMMA
);
data
.
append
(
"#Gets"
).
append
(
COMMA
).
append
(
"#Puts"
).
append
(
COMMA
);
data
.
append
(
"GetResponseTime"
).
append
(
COMMA
);
data
.
append
(
"PutResponseTime"
).
append
(
COMMA
);
data
.
append
(
"GetTpt"
).
append
(
COMMA
);
data
.
append
(
"PutTpt"
).
append
(
COMMA
);
data
.
append
(
"AvgRequestLatency"
).
append
(
COMMA
).
append
(
"AvgThroughput"
);
data
.
append
(
COMMA
).
append
(
"Put%"
);
data
.
append
(
"
\n
"
);
}
outfile
.
open
(
STATISTIC_FILE
,
std
::
ios_base
::
app
);
if
(
outfile
.
is_open
()){
data
.
append
(
to_string
(
maxThreads
)).
append
(
COMMA
).
append
(
to_string
(
flowWeight
)).
append
(
COMMA
).
append
(
to_string
(
tmp
).
append
(
COMMA
));
data
.
append
(
to_string
(
total_G
)).
append
(
COMMA
);
data
.
append
(
to_string
(
total_P
)).
append
(
COMMA
);
data
.
append
(
to_string
(
average_response_time_G
)).
append
(
COMMA
);
data
.
append
(
to_string
(
average_response_time_P
)).
append
(
COMMA
);
//data.append(to_string(total_G + total_P)).append(COMMA);
data
.
append
(
to_string
(
throughput_G
)).
append
(
COMMA
);
data
.
append
(
to_string
(
throughput_P
)).
append
(
COMMA
);
data
.
append
(
to_string
(
average_response_time
)).
append
(
COMMA
);
data
.
append
(
to_string
(
throughput
)).
append
(
COMMA
);
data
.
append
(
to_string
(
percentP
));
}
data
.
append
(
"
\n
"
);
outfile
<<
data
;
outfile
.
close
();
exit
(
0
);
return
0
;
}
inline
bool
fileExists
(
const
std
::
string
&
name
)
{
struct
stat
buffer
;
return
(
stat
(
name
.
c_str
(),
&
buffer
)
==
0
);
}
void
get
(
Network
&
user
,
UserEquipment
&
ue
,
int
key
){
return
ue
.
get
(
user
,
key
);
}
void
put
(
Network
&
user
,
UserEquipment
&
ue
,
int
key
,
int
val
){
return
ue
.
put
(
user
,
key
,
val
);
}
void
getG
(
Network
&
user
,
UserEquipment
&
ue
,
int
key
){
return
ue
.
getG
(
user
,
key
);
}
void
putG
(
Network
&
user
,
UserEquipment
&
ue
,
int
key
,
int
val
){
return
ue
.
putG
(
user
,
key
,
val
);
}
void
setMix
(
int
traffic_type
){
//nPut & nGet are used to generate varied load as put:get
//0---1:20---5% put
//1---1:10---10% put
//2---1:5---18%
//3---1:3---25%
//4---1:1---50%
//5---2:1---66%
//6---3:1---75%
//7---1:0---100%
switch
(
traffic_type
){
case
0
:
nPut
=
1
;
nGet
=
20
;
break
;
case
1
:
nPut
=
1
;
nGet
=
10
;
break
;
case
2
:
nPut
=
1
;
nGet
=
5
;
break
;
case
3
:
nPut
=
1
;
nGet
=
3
;
break
;
case
4
:
nPut
=
1
;
nGet
=
1
;
break
;
case
5
:
nPut
=
2
;
nGet
=
1
;
break
;
case
6
:
nPut
=
3
;
nGet
=
1
;
break
;
case
7
:
nPut
=
1
;
nGet
=
0
;
break
;
default:
cout
<<
"Incorrect traffic type"
<<
endl
;
break
;
}
}
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/client.h
0 → 100755
View file @
f7053183
#include "ue.h"
#include "utils.h"
// Thread function for each UE
void
*
multithreading_func
(
void
*
);
void
get
(
Network
&
,
UserEquipment
&
,
int
);
void
put
(
Network
&
,
UserEquipment
&
,
int
,
int
);
void
getG
(
Network
&
,
UserEquipment
&
,
int
);
void
putG
(
Network
&
,
UserEquipment
&
,
int
,
int
);
inline
bool
fileExists
(
const
std
::
string
&
);
void
setMix
(
int
);
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/inst.csv
0 → 100644
View file @
f7053183
25428.000000,0.187694
16728.199219,0.190937
15381.000000,0.192013
15286.099609,0.193308
13028.700195,0.187651
10884.599609,0.181128
14615.400391,0.282102
12454.599609,0.284142
9205.299805,0.260110
8437.200195,0.233873
8024.600098,0.245885
8480.500000,0.232647
14092.799805,0.133125
15608.900391,0.125049
14706.700195,0.132965
15171.400391,0.128858
22904.599609,0.168836
23514.900391,0.166994
20675.199219,0.174134
14949.299805,0.197522
14959.099609,0.197415
8900.299805,0.192785
25924.000000,0.151526
24990.199219,0.148216
23135.300781,0.128011
20938.400391,0.135729
20816.099609,0.120420
20189.300781,0.104460
22609.099609,0.172755
22630.199219,0.165605
19244.400391,0.154879
19873.199219,0.152041
16872.400391,0.140997
15135.500000,0.128922
12770.900391,0.365437
2677.100098,1.034232
5392.899902,0.383199
3517.000000,0.582586
2353.300049,0.535475
5000.000000,0.250500
5000.000000,0.250501
5000.000000,0.249650
5000.000000,0.251881
10000.000000,0.101549
10000.000000,0.101497
10000.000000,0.101372
10000.000000,0.101449
10000.000000,0.101501
20054.599609,0.143136
15646.299805,0.125783
15478.200195,0.129734
13396.299805,0.130019
9000.000000,0.112075
18893.099609,0.203768
14833.400391,0.201728
14799.500000,0.202068
12382.500000,0.195880
10610.099609,0.190871
25358.800781,0.156851
25519.199219,0.156733
27429.400391,0.157607
24092.599609,0.158162
24969.199219,0.152184
21528.599609,0.200482
15957.599609,0.200924
15921.200195,0.200489
14149.700195,0.200932
11921.299805,0.201255
19969.599609,0.144780
13990.400391,0.141818
13957.700195,0.146047
26573.199219,0.151906
21307.900391,0.149899
20895.500000,0.148847
18813.699219,0.151349
10439.700195,0.190038
10188.700195,0.195399
27588.599609,0.151053
25066.400391,0.144967
12424.799805,0.165251
11837.900391,0.159651
10864.900391,0.172589
19436.000000,0.157061
9980.000000,0.197959
24272.400391,0.114264
27040.900391,0.110309
28006.599609,0.109475
33637.500000,0.124675
31639.400391,0.122455
27352.400391,0.108127
27478.900391,0.107734
29262.800781,0.119911
24717.300781,0.112505
18220.500000,0.109712
31612.900391,0.122583
29278.599609,0.116684
25068.699219,0.115422
28464.900391,0.109554
28492.099609,0.105585
23049.099609,0.115809
9246.000000,0.108822
9000.000000,0.116574
24914.599609,0.113062
25871.000000,0.118098
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/makefile
0 → 100755
View file @
f7053183
all
:
client
CLIENT_P
=
client.cpp client.h utils.cpp utils.h network.cpp network.h ue.cpp ue.h
CLIENT_R
=
g++ client.cpp client.h utils.cpp utils.h network.cpp network.h ue.cpp ue.h
-std
=
c++11
-o
client
-lpthread
-lcrypto
client
:
$(CLIENT_P)
$(CLIENT_R)
clean
:
rm
-f
client
*
~
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/network.cpp
0 → 100755
View file @
f7053183
/*************************************************************************
* * This file contains all the socket level functions that is used by UE. *************************************************************************/
#include "network.h"
//Below are the files included for raw packets
#include<stdio.h> //for printf
#include<string.h> //memset
#include<sys/socket.h> //for socket ofcourse
#include<stdlib.h> //for exit(0);
#include<errno.h> //For errno - the error number
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/ip.h> //Provides declarations for ip header
#include <unistd.h> //Used to get PID of current process
#include<netinet/ip_icmp.h> //Provides declarations for icmp header
//#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/tcp.h> //Provides declarations for tcp header
//#include<netinet/ip.h> //Provides declarations for ip header
#include<netinet/if_ether.h> //For ETH_P_ALL
#include<net/ethernet.h> //For ether_header
//#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/types.h>
//#include<unistd.h>
Network
::
Network
(
int
ID
){
tID
=
2000
+
ID
;
//use global tID to distinguish between threads
//cout<<"TID= "<<tID<<endl;
//Create a raw socket of type IPPROTO
client_socket
=
socket
(
AF_INET
,
SOCK_RAW
,
IPPROTO_RAW
);
if
(
MY_DEBUG
){
cout
<<
"Raw Send Socket created"
<<
endl
;
}
//client_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if
(
client_socket
<
0
){
cout
<<
"ERROR opening UDP socket"
<<
endl
;
exit
(
1
);
}
sock_raw
=
socket
(
AF_PACKET
,
SOCK_RAW
,
htons
(
ETH_P_ALL
))
;
if
(
MY_DEBUG
){
cout
<<
"Raw Receive Socket created"
<<
endl
;
}
//int sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
//setsockopt(sock_raw , SOL_SOCKET , SO_BINDTODEVICE , "eth1" , strlen("eth1")+ 1 );
if
(
sock_raw
<
0
)
{
//Print the error with proper message
perror
(
"Socket Error"
);
//return 1;
}
}
struct
pseudo_header
{
u_int32_t
source_address
;
u_int32_t
dest_address
;
u_int8_t
placeholder
;
u_int8_t
protocol
;
u_int16_t
udp_length
;
};
/*
Generic checksum calculation function
*/
unsigned
short
csum
(
unsigned
short
*
ptr
,
int
nbytes
)
{
register
long
sum
;
unsigned
short
oddbyte
;
register
short
answer
;
sum
=
0
;
while
(
nbytes
>
1
)
{
sum
+=*
ptr
++
;
nbytes
-=
2
;
}
if
(
nbytes
==
1
)
{
oddbyte
=
0
;
*
((
u_char
*
)
&
oddbyte
)
=*
(
u_char
*
)
ptr
;
sum
+=
oddbyte
;
}
sum
=
(
sum
>>
16
)
+
(
sum
&
0xffff
);
sum
=
sum
+
(
sum
>>
16
);
answer
=
(
short
)
~
sum
;
return
(
answer
);
}
/*
* This function configures the port number and IP address of the created socket.
*/
void
Network
::
input_server_details
(
int
server_port
,
const
char
*
server_address
){
int
status
;
this
->
server_port
=
server_port
;
this
->
server_address
=
server_address
;
bzero
((
char
*
)
&
server_sock_addr
,
sizeof
(
server_sock_addr
));
server_sock_addr
.
sin_family
=
AF_INET
;
server_sock_addr
.
sin_port
=
htons
(
server_port
);
// Store this IP address in server_sock_addr; pton supports IPv6 while aton does not
status
=
inet_pton
(
AF_INET
,
server_address
,
&
(
server_sock_addr
.
sin_addr
));
if
(
status
==
0
){
cout
<<
"ERROR: Invalid IP address"
<<
endl
;
exit
(
EXIT_FAILURE
);
}
}
/*
* This function reads from the UDP socket.
*/
void
Network
::
read_data
(){
int
status
=
0
;
unsigned
char
*
my_buffer
;
//Receive a packet
int
c
=
0
;
while
(
status
!=
17
||
!
tflag
){
bzero
(
client_buffer
,
BUFFER_SIZE
);
data_size
=
recvfrom
(
sock_raw
,
client_buffer
,
BUFFER_SIZE
-
1
,
0
,
&
saddr
,
(
socklen_t
*
)
&
saddr_size
);
status
=
ProcessPacket
((
unsigned
char
*
)
client_buffer
,
data_size
);
}
}
int
Network
::
ProcessPacket
(
unsigned
char
*
buffer
,
int
size
)
{
int
tcp
=
0
,
udp
=
0
,
icmp
=
0
,
others
=
0
,
igmp
=
0
,
total
=
0
,
i
,
j
;
++
total
;
//Get the IP Header part of this packet , excluding the ethernet header
struct
iphdr
*
iph
=
(
struct
iphdr
*
)(
buffer
+
sizeof
(
struct
ethhdr
));
switch
(
iph
->
protocol
)
//Check the Protocol and do accordingly...
{
case
17
:
//UDP Protocol
//cout<<"Inside process packet:UDP"<<endl;
//++udp;
print_udp_packet
(
buffer
,
size
);
return
(
17
);
break
;
default:
//Some Other Protocol like ARP etc.
//cout<<"Inside process packet:others";
//++others;
return
(
0
);
break
;
}
}
void
Network
::
print_ip_header
(
unsigned
char
*
Buffer
,
int
Size
)
{
//print_ethernet_header(Buffer , Size);
unsigned
short
iphdrlen
;
struct
iphdr
*
iph
=
(
struct
iphdr
*
)(
Buffer
+
sizeof
(
struct
ethhdr
)
);
iphdrlen
=
iph
->
ihl
*
4
;
memset
(
&
source
,
0
,
sizeof
(
source
));
source
.
sin_addr
.
s_addr
=
iph
->
saddr
;
memset
(
&
dest
,
0
,
sizeof
(
dest
));
dest
.
sin_addr
.
s_addr
=
iph
->
daddr
;
}
void
Network
::
print_udp_packet
(
unsigned
char
*
Buffer
,
int
Size
)
{
unsigned
short
iphdrlen
;
struct
iphdr
*
iph
=
(
struct
iphdr
*
)(
Buffer
+
sizeof
(
struct
ethhdr
));
iphdrlen
=
iph
->
ihl
*
4
;
struct
udphdr
*
udph
=
(
struct
udphdr
*
)(
Buffer
+
iphdrlen
+
sizeof
(
struct
ethhdr
));
int
header_size
=
sizeof
(
struct
ethhdr
)
+
iphdrlen
+
sizeof
udph
;
print_ip_header
(
Buffer
,
Size
);
if
((
int
)
ntohs
(
udph
->
dest
)
==
tID
)
{
tflag
=
true
;
}
else
tflag
=
false
;
strcpy
(
client_buffer
,
(
const
char
*
)
Buffer
+
header_size
);
}
void
Network
::
write_data2
(
int
data_len
){
//Datagram to represent the packet
char
datagram
[
4096
]
,
source_ip
[
32
]
,
*
data
,
*
pseudogram
;
//zero out the packet buffer
memset
(
datagram
,
0
,
4096
);
//IP header
struct
iphdr
*
iph
=
(
struct
iphdr
*
)
datagram
;
//UDP header
struct
udphdr
*
udph
=
(
struct
udphdr
*
)
(
datagram
+
sizeof
(
struct
ip
));
struct
sockaddr_in
server_sock_addr
;
struct
pseudo_header
psh
;
//Data part
data
=
datagram
+
sizeof
(
struct
iphdr
)
+
sizeof
(
struct
udphdr
);
if
(
MY_DEBUG
){
cout
<<
"data len = "
<<
data_len
<<
endl
;
}
memcpy
(
data
,
client_buffer
,
data_len
);
bzero
(
client_buffer
,
BUFFER_SIZE
);
if
(
MY_DEBUG
){
cout
<<
"SENDING - "
<<
data
<<
endl
;
}
//cout<<"Thread ID- "<<tID<<endl;
/*int c = 0;
while (client_buffer[c] != '\0') {
data[c] = client_buffer[c];
c++;
}
data[c] = '\0';*/
//some address resolution
strcpy
(
source_ip
,
CLIENT_IP
);
//Source IP
server_sock_addr
.
sin_family
=
AF_INET
;
server_sock_addr
.
sin_port
=
htons
(
gw_port
);
server_sock_addr
.
sin_addr
.
s_addr
=
inet_addr
(
DGW_IP
);
//Dest IP
//Bind the client socket to UDP port
//bind(client_socket, (struct sockaddr *)& server_sock_addr, sizeof(server_sock_addr));
//Tell the kernel that we build our own packets
/*int one = 1;
const int *val = &one;
if(setsockopt(client_socket, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0){
perror("setsockopt() error");
exit(-1);
}*/
//Fill in the IP Header
iph
->
ihl
=
5
;
iph
->
version
=
4
;
iph
->
tos
=
stoi
(
"1"
)
*
4
;
//16;
iph
->
tot_len
=
sizeof
(
struct
iphdr
)
+
sizeof
(
struct
udphdr
)
+
data_len
;
iph
->
id
=
htonl
(
0
);
//htonl (12345); //Id of this packet
iph
->
frag_off
=
0
;
// iph->ttl = 255;
iph
->
ttl
=
64
;
iph
->
protocol
=
IPPROTO_UDP
;
iph
->
check
=
0
;
//Set to 0 before calculating checksum
iph
->
saddr
=
inet_addr
(
source_ip
);
//Spoof the source ip address
iph
->
daddr
=
server_sock_addr
.
sin_addr
.
s_addr
;
//Ip checksum
iph
->
check
=
csum
((
unsigned
short
*
)
datagram
,
iph
->
tot_len
);
//int pid = getpid();
//int parentsPID = getppid();
//UDP header
//udph->source = htons (RAN_UDP_PORT);
udph
->
source
=
htons
(
tID
);
udph
->
dest
=
htons
(
gw_port
);
// htons(stoi(msg_id)+2000);
udph
->
len
=
htons
(
8
+
data_len
);
//tcp header size
udph
->
check
=
0
;
//leave checksum 0 now, filled later by pseudo header
//Now the UDP checksum using the pseudo header
psh
.
source_address
=
inet_addr
(
source_ip
);
psh
.
dest_address
=
server_sock_addr
.
sin_addr
.
s_addr
;
psh
.
placeholder
=
0
;
psh
.
protocol
=
IPPROTO_UDP
;
psh
.
udp_length
=
htons
(
sizeof
(
struct
udphdr
)
+
data_len
);
int
psize
=
sizeof
(
struct
pseudo_header
)
+
sizeof
(
struct
udphdr
)
+
data_len
;
pseudogram
=
(
char
*
)
malloc
(
psize
);
memcpy
(
pseudogram
,
(
char
*
)
&
psh
,
sizeof
(
struct
pseudo_header
));
memcpy
(
pseudogram
+
sizeof
(
struct
pseudo_header
)
,
udph
,
sizeof
(
struct
udphdr
)
+
data_len
);
udph
->
check
=
csum
(
(
unsigned
short
*
)
pseudogram
,
psize
);
int
status
;
status
=
sendto
(
client_socket
,
datagram
,
iph
->
tot_len
,
0
,
(
struct
sockaddr
*
)
&
server_sock_addr
,
sizeof
(
server_sock_addr
));
report_error
(
status
);
}
/*
* This function writes to the UDP socket.
//We pass msg_id to write_data to set IPToS field
*/
void
Network
::
write_data
(
string
msg_id
){
//Datagram to represent the packet
char
datagram
[
4096
]
,
source_ip
[
32
]
,
*
data
,
*
pseudogram
;
//zero out the packet buffer
memset
(
datagram
,
0
,
4096
);
//IP header
struct
iphdr
*
iph
=
(
struct
iphdr
*
)
datagram
;
//UDP header
struct
udphdr
*
udph
=
(
struct
udphdr
*
)
(
datagram
+
sizeof
(
struct
ip
));
struct
sockaddr_in
server_sock_addr
;
struct
pseudo_header
psh
;
//Data part
data
=
datagram
+
sizeof
(
struct
iphdr
)
+
sizeof
(
struct
udphdr
);
strcpy
(
data
,
client_buffer
);
bzero
(
client_buffer
,
BUFFER_SIZE
);
if
(
MY_DEBUG
){
cout
<<
"SENDING - "
<<
data
<<
endl
;
}
//some address resolution
strcpy
(
source_ip
,
CLIENT_IP
);
//Source IP
server_sock_addr
.
sin_family
=
AF_INET
;
server_sock_addr
.
sin_port
=
htons
(
gw_port
);
server_sock_addr
.
sin_addr
.
s_addr
=
inet_addr
(
DGW_IP
);
//Dest IP
//Fill in the IP Header
iph
->
ihl
=
5
;
iph
->
version
=
4
;
iph
->
tos
=
stoi
(
msg_id
)
*
4
;
//16;
iph
->
tot_len
=
sizeof
(
struct
iphdr
)
+
sizeof
(
struct
udphdr
)
+
strlen
(
data
);
iph
->
id
=
htonl
(
0
);
//htonl (12345); //Id of this packet
iph
->
frag_off
=
0
;
iph
->
ttl
=
255
;
iph
->
protocol
=
IPPROTO_UDP
;
iph
->
check
=
0
;
//Set to 0 before calculating checksum
iph
->
saddr
=
inet_addr
(
source_ip
);
//Spoof the source ip address
iph
->
daddr
=
server_sock_addr
.
sin_addr
.
s_addr
;
//Ip checksum
iph
->
check
=
csum
((
unsigned
short
*
)
datagram
,
iph
->
tot_len
);
//UDP header
//udph->source = htons (RAN_UDP_PORT);
udph
->
source
=
htons
(
tID
);
udph
->
dest
=
htons
(
gw_port
);
// htons(stoi(msg_id)+2000);
udph
->
len
=
htons
(
8
+
strlen
(
data
));
//tcp header size
udph
->
check
=
0
;
//leave checksum 0 now, filled later by pseudo header
//Now the UDP checksum using the pseudo header
psh
.
source_address
=
inet_addr
(
source_ip
);
psh
.
dest_address
=
server_sock_addr
.
sin_addr
.
s_addr
;
psh
.
placeholder
=
0
;
psh
.
protocol
=
IPPROTO_UDP
;
psh
.
udp_length
=
htons
(
sizeof
(
struct
udphdr
)
+
strlen
(
data
)
);
int
psize
=
sizeof
(
struct
pseudo_header
)
+
sizeof
(
struct
udphdr
)
+
strlen
(
data
);
pseudogram
=
(
char
*
)
malloc
(
psize
);
memcpy
(
pseudogram
,
(
char
*
)
&
psh
,
sizeof
(
struct
pseudo_header
));
memcpy
(
pseudogram
+
sizeof
(
struct
pseudo_header
)
,
udph
,
sizeof
(
struct
udphdr
)
+
strlen
(
data
));
udph
->
check
=
csum
(
(
unsigned
short
*
)
pseudogram
,
psize
);
int
status
;
status
=
sendto
(
client_socket
,
datagram
,
iph
->
tot_len
,
0
,
(
struct
sockaddr
*
)
&
server_sock_addr
,
sizeof
(
server_sock_addr
));
report_error
(
status
);
}
/*
* This function reads from the UDP socket in the form of unsigned char.
*/
void
Network
::
read_byte
(){
int
status
;
bzero
(
client_byte_buffer
,
BUFFER_SIZE
);
status
=
recvfrom
(
client_socket
,
client_byte_buffer
,
BUFFER_SIZE
-
1
,
0
,
NULL
,
NULL
);
report_error
(
status
);
}
/*
* This function writes to the UDP socket in the form of unsigned char.
*/
void
Network
::
write_byte
(){
int
status
;
status
=
sendto
(
client_socket
,
client_byte_buffer
,
strlen
((
char
*
)
client_byte_buffer
),
0
,(
struct
sockaddr
*
)
&
server_sock_addr
,
sizeof
(
server_sock_addr
));
report_error
(
status
);
}
// Destructor: Close the UDP client socket
Network
::~
Network
(){
close
(
client_socket
);
close
(
sock_raw
);
}
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/network.h
0 → 100755
View file @
f7053183
#ifndef UTILS_H
#define UTILS_H
#include <fcntl.h>
#include "utils.h"
#endif
class
Network
{
public:
int
tID
;
int
client_socket
;
char
client_buffer
[
BUFFER_SIZE
];
char
write_client_buffer
[
BUFFER_SIZE
];
char
write_client_byte_buffer
[
BUFFER_SIZE
];
int
sock_raw
;
//To receive raw packets
int
saddr_size
,
data_size
;
struct
sockaddr
saddr
;
// Byte array in C++
unsigned
char
client_byte_buffer
[
BUFFER_SIZE
];
int
server_port
;
const
char
*
server_address
;
struct
sockaddr_in
server_sock_addr
;
struct
sockaddr_in
source
,
dest
;
//bool flag=false; //flag to test the right dest IP for rcv data
bool
tflag
=
false
;
//flag to test dest UDP port for demux of packets
// Constructor
Network
(
int
);
// Socket methods
void
input_server_details
(
int
,
const
char
*
);
void
read_data
();
void
write_data
(
string
);
void
write_data2
(
int
);
void
read_byte
();
void
write_byte
();
int
sendUEData
(
int
,
string
,
string
,
int
,
int
,
int
,
string
,
size_t
);
// Utility functions
string
GetStdoutFromCommand
(
string
cmd
);
string
runIperfCommand
(
string
cmd
,
string
srcIp
);
//Raw packet functions
int
ProcessPacket
(
unsigned
char
*
,
int
);
void
print_ip_header
(
unsigned
char
*
,
int
);
void
print_udp_packet
(
unsigned
char
*
,
int
);
// Destructor
~
Network
();
};
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/route.sh
0 → 100755
View file @
f7053183
sudo
route add
-net
192.168.3.0 netmask 255.255.255.0 gw 192.168.1.2 dev eth1
sudo
route add
-net
192.168.4.0 netmask 255.255.255.0 gw 192.168.1.2 dev eth1
sudo
route add
-net
192.168.5.0 netmask 255.255.255.0 gw 192.168.1.2 dev eth1
sudo
route add
-net
192.168.6.0 netmask 255.255.255.0 gw 192.168.1.2 dev eth1
sudo
route add
-net
192.168.7.0 netmask 255.255.255.0 gw 192.168.1.2 dev eth1
sudo
route add
-net
192.168.8.0 netmask 255.255.255.0 gw 192.168.1.2 dev eth1
sudo
route add
-net
192.168.9.0 netmask 255.255.255.0 gw 192.168.1.2 dev eth1
sudo
route add
-net
192.168.10.0 netmask 255.255.255.0 gw 192.168.1.2 dev eth1
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/stats.csv
0 → 100644
View file @
f7053183
12770.900391,0.365437
2677.100098,1.034232
5392.899902,0.383199
3517.000000,0.582586
2353.300049,0.535475
#MaxThreads,FlowWeight,ExecutionTime,#Gets,#Puts,GetResponseTime,PutResponseTime,GetTpt,PutTpt,AvgRequestLatency,AvgThroughput,Put%
4,1,60.000000,0,296928,nan,453.192370,0.000000,4948.800000,0.000453,4948.800000,100.000000
5000.000000,0.250500
5000.000000,0.250501
5000.000000,0.249650
5000.000000,0.251881
1,1,60.000000,0,244525,nan,245.083443,0.000000,4075.416667,0.000245,4075.416667,100.000000
10000.000000,0.101549
10000.000000,0.101497
10000.000000,0.101372
10000.000000,0.101449
10000.000000,0.101501
1,1,60.000000,0,589653,nan,101.455861,0.000000,9827.550000,0.000101,9827.550000,100.000000
2,1,60.000000,0,87165,nan,111.031653,0.000000,1452.750000,0.000111,1452.750000,100.000000
4,1,6.000000,0,148511,nan,155.959969,0.000000,24751.833333,0.000156,24751.833333,100.000000
20054.599609,0.143136
15646.299805,0.125783
15478.200195,0.129734
13396.299805,0.130019
9000.000000,0.112075
4,1,60.000000,0,819535,nan,128.644840,0.000000,13658.916667,0.000129,13658.916667,100.000000
8,1,6.000000,0,94553,nan,223.085222,0.000000,15758.833333,0.000223,15758.833333,100.000000
6,1,6.000000,0,128340,nan,195.318389,0.000000,21390.000000,0.000195,21390.000000,100.000000
18893.099609,0.203768
14833.400391,0.201728
14799.500000,0.202068
12382.500000,0.195880
10610.099609,0.190871
6,1,60.000000,0,808249,nan,198.777890,0.000000,13470.816667,0.000199,13470.816667,100.000000
25358.800781,0.156851
25519.199219,0.156733
27429.400391,0.157607
24092.599609,0.158162
24969.199219,0.152184
#### 2 QUEUES
4,1,60.000000,0,1408391,nan,155.270227,0.000000,23473.183333,0.000155,23473.183333,100.000000
21528.599609,0.200482
15957.599609,0.200924
15921.200195,0.200489
14149.700195,0.200932
11921.299805,0.201255
6,1,60.000000,0,895084,nan,200.783456,0.000000,14673.508197,0.000201,14673.508197,100.000000
19969.599609,0.144780
13990.400391,0.141818
13957.700195,0.146047
#### 6 QUEUES
4,1,30.000000,0,479904,nan,144.220271,0.000000,15480.774194,0.000144,15480.774194,100.000000
26573.199219,0.151906
21307.900391,0.149899
20895.500000,0.148847
18813.699219,0.151349
10439.700195,0.190038
10188.700195,0.195399
4,1,60.000000,0,1082663,nan,158.573467,0.000000,18044.383333,0.000159,18044.383333,100.000000
27588.599609,0.151053
25066.400391,0.144967
12424.799805,0.165251
11837.900391,0.159651
10864.900391,0.172589
4,1,60.000000,0,921223,nan,157.320314,0.000000,15353.716667,0.000157,15353.716667,100.000000
19436.000000,0.157061
9980.000000,0.197959
4,1,30.000000,0,394022,nan,175.833393,0.000000,13134.066667,0.000176,13134.066667,100.000000
24272.400391,0.114264
27040.900391,0.110309
28006.599609,0.109475
4,1,30.000000,0,800178,nan,111.153595,0.000000,26672.600000,0.000111,26672.600000,100.000000
33637.500000,0.124675
31639.400391,0.122455
4,1,30.000000,0,973877,nan,123.065053,0.000000,32462.566667,0.000123,32462.566667,100.000000
27352.400391,0.108127
27478.900391,0.107734
4,1,30.000000,0,840234,nan,107.064149,0.000000,28007.800000,0.000107,28007.800000,100.000000
29262.800781,0.119911
24717.300781,0.112505
18220.500000,0.109712
4,1,30.000000,0,725058,nan,114.768152,0.000000,24168.600000,0.000115,24168.600000,100.000000
31612.900391,0.122583
29278.599609,0.116684
25068.699219,0.115422
4,1,30.000000,0,861042,nan,118.457599,0.000000,28701.400000,0.000118,28701.400000,100.000000
28464.900391,0.109554
28492.099609,0.105585
4,1,30.000000,0,762393,nan,107.451678,0.000000,25413.100000,0.000107,25413.100000,100.000000
23049.099609,0.115809
9246.000000,0.108822
9000.000000,0.116574
4,1,60.000000,0,452292,nan,113.807584,0.000000,7538.200000,0.000114,7538.200000,100.000000
24914.599609,0.113062
25871.000000,0.118098
4,1,30.000000,0,782060,nan,114.854963,0.000000,26068.666667,0.000115,26068.666667,100.000000
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/ue.cpp
0 → 100755
View file @
f7053183
/********************************************************************
* This file contains all the functionalities associated with a UE. *
********************************************************************/
#include "ue.h"
#include <time.h>
/* Message codes */
//Message from client to Switch/LB/Server
string
GET
=
"1"
;
string
GETG
=
"2"
;
string
PUT
=
"3"
;
string
PUTG
=
"4"
;
//Message from Server to Controller LB
//string SERVERSTATS = "5";
//Reply from LB to Client(ACK)
string
SERVERFOUND
=
"6"
;
//string FIN = "7";
char
SEPARATOR
[]
=
"@:##:@"
;
/*
* Constructor: Create a UE object.
*/
UserEquipment
::
UserEquipment
(
int
ue_num
){
}
void
UserEquipment
::
get
(
Network
&
user
,
int
key
){
string
send
,
receive
;
vector
<
string
>
tmpArray
;
time_t
curTime
;
time
(
&
curTime
);
send
=
GET
+
SEPARATOR
+
to_string
(
key
);
bzero
(
user
.
client_buffer
,
BUFFER_SIZE
);
sprintf
(
user
.
client_buffer
,
"%s"
,
send
.
c_str
());
user
.
write_data
(
GET
);
//We pass msg_id to write_data to set IPToS field
time
(
&
curTime
);
// Receive reply from LB
user
.
read_data
();
time
(
&
curTime
);
receive
=
(
string
)
(
user
.
client_buffer
);
if
(
receive
.
find
(
SEPARATOR
)
!=
std
::
string
::
npos
)
{
tmpArray
=
split
(
user
.
client_buffer
,
SEPARATOR
);
if
(
tmpArray
[
0
]
==
SERVERFOUND
){
if
(
DO_DEBUG
){
cout
<<
"VALUE : "
<<
tmpArray
[
1
]
<<
endl
;
}
}
//cout <<"VALUE : "<<tmpArray[1]<<endl;
//<<"VALUE: "<<tmpArray[2]<<endl;
//cout<<"Received"<<endl;
}
}
void
UserEquipment
::
getG
(
Network
&
user
,
int
key
){
string
send
,
receive
;
vector
<
string
>
tmpArray
;
time_t
curTime
;
////////////////// Global GET /////////////////
time
(
&
curTime
);
send
=
GETG
+
SEPARATOR
+
to_string
(
key
);
bzero
(
user
.
client_buffer
,
BUFFER_SIZE
);
sprintf
(
user
.
client_buffer
,
"%s"
,
send
.
c_str
());
user
.
write_data
(
GETG
);
//We pass msg_id to write_data to set IPToS field
time
(
&
curTime
);
// Receive reply from KV
user
.
read_data
();
time
(
&
curTime
);
receive
=
(
string
)
(
user
.
client_buffer
);
if
(
receive
.
find
(
SEPARATOR
)
!=
std
::
string
::
npos
)
{
tmpArray
=
split
(
user
.
client_buffer
,
SEPARATOR
);
if
(
tmpArray
[
0
]
==
SERVERFOUND
){
if
(
DO_DEBUG
){
cout
<<
"VALUE : "
<<
tmpArray
[
1
]
<<
endl
;
}
}
//cout <<"VALUE : "<<tmpArray[1]<<endl;
//<<"VALUE: "<<tmpArray[2]<<endl;
//cout<<"Received"<<endl;
}
///////////////// Global GET ends ////////////////
}
void
UserEquipment
::
put
(
Network
&
user
,
int
key
,
int
val
){
string
send
,
receive
;
vector
<
string
>
tmpArray
;
time_t
curTime
;
time
(
&
curTime
);
send
=
PUT
+
SEPARATOR
+
to_string
(
key
)
+
SEPARATOR
+
to_string
(
val
);
bzero
(
user
.
client_buffer
,
BUFFER_SIZE
);
sprintf
(
user
.
client_buffer
,
"%s"
,
send
.
c_str
());
user
.
write_data
(
PUT
);
time
(
&
curTime
);
// Receive reply from KV
user
.
read_data
();
time
(
&
curTime
);
receive
=
(
string
)
(
user
.
client_buffer
);
if
(
receive
.
find
(
SEPARATOR
)
!=
std
::
string
::
npos
)
{
tmpArray
=
split
(
user
.
client_buffer
,
SEPARATOR
);
if
(
tmpArray
[
0
]
==
SERVERFOUND
){
if
(
DO_DEBUG
){
cout
<<
"PUT COMPLETE : "
<<
tmpArray
[
0
]
<<
endl
;
}
}
}
}
void
UserEquipment
::
putG
(
Network
&
user
,
int
key
,
int
val
){
string
send
,
receive
;
vector
<
string
>
tmpArray
;
time_t
curTime
;
////////// Global PUT ////////////////////////////
time
(
&
curTime
);
//send = PUTG + SEPARATOR + to_string(key) + SEPARATOR + to_string(val);
uint16_t
type
=
htons
(
0x4
);
uint16_t
sep1
=
htons
(
0x403A
);
uint16_t
sep2
=
htons
(
0x2323
);
uint16_t
sep3
=
htons
(
0x3A40
);
uint32_t
k
=
htonl
(
key
);
uint32_t
v
=
htonl
(
val
);
bzero
(
user
.
client_buffer
,
BUFFER_SIZE
);
int
len
=
0
;
memcpy
(
user
.
client_buffer
,
&
type
,
2
);
len
=
len
+
2
;
memcpy
(
user
.
client_buffer
+
len
,
&
sep1
,
2
);
len
=
len
+
2
;
memcpy
(
user
.
client_buffer
+
len
,
&
sep2
,
2
);
len
=
len
+
2
;
memcpy
(
user
.
client_buffer
+
len
,
&
sep3
,
2
);
len
=
len
+
2
;
memcpy
(
user
.
client_buffer
+
len
,
&
k
,
sizeof
(
int
));
len
=
len
+
sizeof
(
int
);
memcpy
(
user
.
client_buffer
+
len
,
&
sep1
,
2
);
len
=
len
+
2
;
memcpy
(
user
.
client_buffer
+
len
,
&
sep2
,
2
);
len
=
len
+
2
;
memcpy
(
user
.
client_buffer
+
len
,
&
sep3
,
2
);
len
=
len
+
2
;
memcpy
(
user
.
client_buffer
+
len
,
&
v
,
sizeof
(
int
));
len
=
len
+
sizeof
(
int
);
//memcpy(user.client_buffer+len, &type, 2);
//len=len+2;
//sprintf(user.client_buffer,"%s",send.c_str());
user
.
write_data2
(
len
);
time
(
&
curTime
);
// Receive reply from LB
user
.
read_data
();
time
(
&
curTime
);
receive
=
(
string
)
(
user
.
client_buffer
);
/*if (receive.find(SEPARATOR) != std::string::npos) {
tmpArray = split(user.client_buffer, SEPARATOR);
if(tmpArray[0] == SERVERFOUND){
if(DO_DEBUG){
cout <<"GLOBAL PUT COMPLETE : "<<tmpArray[0]<<endl;
}
}
}*/
////////// Global PUT ENDS ////////////////////////////
}
UserEquipment
::~
UserEquipment
(){
// Dummy destructor
}
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/ue.h
0 → 100755
View file @
f7053183
#include "network.h"
class
UserEquipment
{
public:
// Constructor
UserEquipment
(
int
);
/* Functions */
void
get
(
Network
&
,
int
);
void
put
(
Network
&
,
int
,
int
);
void
getG
(
Network
&
,
int
);
void
putG
(
Network
&
,
int
,
int
);
// Destructor
~
UserEquipment
();
};
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/utils.cpp
0 → 100755
View file @
f7053183
/****************************************************************************************
* This file contains all the utility functions such as integrity and cipher functions. *
****************************************************************************************/
#include "utils.h"
#include <random>
mutex
mtx
;
//int base_thread_ID=1;
//int gw_port = 9876;
int
gw_port
=
5858
;
const
char
*
gw_address
=
DGW_IP
;
// Packets should reach the default switch, so setting its IP to that of default switch
default_random_engine
generator
;
std
::
random_device
rd
;
std
::
mt19937
gen
(
rd
());
std
::
uniform_real_distribution
<>
att
(
0
,
1
);
std
::
uniform_real_distribution
<>
serv
(
0
,
1
);
int
get_mix
(
vector
<
int
>
weights
){
int
sum
=
0
;
for
(
int
i
=
0
;
i
<
weights
.
size
();
i
++
){
sum
+=
weights
[
i
];
}
int
rnd
=
rand
()
%
sum
+
1
;
if
(
DO_DEBUG
)
cout
<<
"RANDOM "
<<
rnd
<<
endl
;
for
(
int
i
=
0
;
i
<
weights
.
size
();
i
++
)
{
if
(
rnd
<=
weights
[
i
])
return
i
;
rnd
-=
weights
[
i
];
}
//assert(!"should never get here");
return
15
;
}
int
my_rand
(){
int
num
;
/* initialize random seed: */
srand
(
time
(
NULL
));
/* generate secret number between 1 and 1000: */
num
=
rand
()
%
200
+
1
;
return
(
num
);
}
void
report_error
(
int
arg
){
if
(
arg
<
0
){
perror
(
"ERROR"
);
exit
(
EXIT_FAILURE
);
}
}
void
print_message
(
string
message
){
cout
<<
"***********************"
<<
endl
;
cout
<<
message
<<
endl
;
cout
<<
"***********************"
<<
endl
;
}
void
print_message
(
string
message
,
int
arg
){
cout
<<
"***********************"
<<
endl
;
cout
<<
message
<<
" "
<<
arg
<<
endl
;
cout
<<
"***********************"
<<
endl
;
}
void
print_message
(
string
message
,
unsigned
long
long
arg
){
cout
<<
"***********************"
<<
endl
;
cout
<<
message
<<
" "
<<
arg
<<
endl
;
cout
<<
"***********************"
<<
endl
;
}
const
char
*
to_char_array
(
unsigned
long
long
arg
){
string
tem
;
stringstream
out
;
out
<<
arg
;
tem
=
out
.
str
();
const
char
*
ans
=
tem
.
c_str
();
return
ans
;
}
string
longToString
(
unsigned
long
long
arg
){
stringstream
out
;
out
<<
arg
;
return
out
.
str
();
}
void
trim
(
string
&
s
){
s
.
erase
(
s
.
find_last_not_of
(
"
\n\r\t
"
)
+
1
);
}
vector
<
string
>
split
(
char
*
str
,
const
char
*
delim
){
vector
<
string
>
ans
;
string
s
(
str
);
string
delimiter
(
delim
);
size_t
pos
=
0
;
std
::
string
token
;
while
((
pos
=
s
.
find
(
delimiter
))
!=
std
::
string
::
npos
)
{
token
=
s
.
substr
(
0
,
pos
);
ans
.
push_back
(
token
);
s
.
erase
(
0
,
pos
+
delimiter
.
length
());
}
ans
.
push_back
(
s
);
return
ans
;
}
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/load_gen/utils.h
0 → 100755
View file @
f7053183
//To delete entries from delay file: sed -i '/^pattern/d' delay.csv
//(C++) Operations: Input/Output
#include <iostream>
#include <math.h>
//(C++) STL Operations: String, Vector, String stream
#include <string>
#include <vector>
#include <sstream>
#include <unordered_map>
#include <queue>
#include <mutex>
// For integrity protection (NAS Signalling)
#include <openssl/hmac.h>
// For encryption/decryption (AES)
#include <openssl/aes.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
//(C) Operations: Input/Output, String, Standard libraries(like atoi, malloc)
#include <stdio.h>
#include <random>
#include <string.h>
#include <stdlib.h>
#include <thread>
//(C) Operations: Socket programming
#include <sys/timeb.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/types.h>
//(C) Operations: Multithreading
#include <pthread.h>
// Raw socket
#include <linux/if_packet.h>
#include <sys/ioctl.h>
#include <bits/ioctls.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ether.h>
//Tun device
#include <linux/if_tun.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <stdarg.h>
//Writing file
#include <fstream>
//#include <atomic>
using
namespace
std
;
#define DO_DEBUG 0
#define MY_DEBUG 0
#define WANT_DELAY_CDF 0
#define UE_PER_THREAD 1000000
/**************************************** Configurable parameters **********************************************/
#define DEFAULT_IF "p0" // Default network interface name *
#define DGW_IP "192.168.220.34" // IP address of DGW machine
#define CLIENT_IP "192.168.220.39" // IP address of RAN machine
#define SINK_SERVER_NETMASK "/16" // Sink subnet netmask
/***************************************************************************************************************/
#define BUFFER_SIZE 300 // Maximum packet size
#define MAX_PACKET_SIZE 2048
#define LINK_MTU 1500 // MTU value for iperf3
#define RAN_UDP_PORT 5858
#define SINK_UDP_PORT 7891
#define COMMA ","
#define STATISTIC_FILE "stats.csv"
#define DELAY_FILE "delay.csv"
#define INST_FILE "inst.csv" //STORES PER PERIOD TPT & LAT
extern
int
gw_port
;
extern
const
char
*
gw_address
;
/* Utility functions */
int
my_rand
();
bool
att_prob
(
float
);
bool
serv_prob
(
float
);
void
report_error
(
int
);
void
print_message
(
string
);
void
print_message
(
string
,
int
);
void
print_message
(
string
,
unsigned
long
long
);
const
char
*
to_char_array
(
unsigned
long
long
);
string
longToString
(
unsigned
long
long
);
void
trim
(
string
&
);
vector
<
string
>
split
(
char
*
,
const
char
*
);
int
get_mix
(
vector
<
int
>
);
code/lsm-tree-impl/smartnic-app/metadata-server-read-offload/load-gen/udp-time.py
0 → 100755
View file @
f7053183
#! /usr/bin/env python
#import os
#os.sys.path.append('/usr/local/lib/python2.7/site-packages')
#print os.sys.path
from
scapy.all
import
*
from
time
import
*
def
QoS_ping
(
host
,
count
=
10
):
packet
=
Ether
(
dst
=
"0c:42:a1:df:ac:49"
)
/
IP
(
dst
=
host
)
#packet = Ether(dst="0c:42:a1:df:ac:49")/IP(dst=host)/UDP(dport=4321)/Raw(load="abc")
#packet = Ether()/IP(dst=host)/ICMP()
t
=
0.0
for
x
in
range
(
count
):
#t1=time()
ans
,
unans
=
srp
(
packet
,
iface
=
"p0"
,
verbose
=
0
)
#t2=time()
rx
=
ans
[
0
][
1
]
tx
=
ans
[
0
][
0
]
delta
=
rx
.
time
-
tx
.
sent_time
#t+=t2-t1
t
+=
delta
return
(
t
/
count
)
*
1000
if
__name__
==
"__main__"
:
total
=
QoS_ping
(
'192.168.220.34'
)
print
"TOTAL"
,
total
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment