From fdde6ec49398cab81ca694e5b6c208b0e41985fe Mon Sep 17 00:00:00 2001 From: Pedro Costa Date: Fri, 21 Feb 2025 20:02:01 +0000 Subject: [PATCH 1/5] task: clang-format cpp code --- .clang-format | 4 +- src/.aspect/cli/config.yaml | 1 + src/.clang-format | 225 ++++++++++++++ src/BUILD | 1 + src/MODULE.bazel | 13 + src/MODULE.bazel.lock | 83 +++++ src/attention_broker/AttentionBrokerServer.cc | 73 ++--- src/attention_broker/AttentionBrokerServer.h | 254 ++++++++------- src/attention_broker/HandleTrie.cc | 100 +++--- src/attention_broker/HandleTrie.h | 87 +++--- src/attention_broker/HebbianNetwork.cc | 89 +++--- src/attention_broker/HebbianNetwork.h | 139 ++++----- src/attention_broker/HebbianNetworkUpdater.cc | 39 ++- src/attention_broker/HebbianNetworkUpdater.h | 95 +++--- src/attention_broker/RequestSelector.cc | 50 ++- src/attention_broker/RequestSelector.h | 73 ++--- src/attention_broker/StimulusSpreader.cc | 120 ++++--- src/attention_broker/StimulusSpreader.h | 150 ++++----- src/attention_broker/WorkerThreads.cc | 60 ++-- src/attention_broker/WorkerThreads.h | 55 ++-- src/commons/SharedQueue.cc | 30 +- src/commons/SharedQueue.h | 37 ++- src/commons/Utils.cc | 44 +-- src/commons/Utils.h | 37 ++- .../DistributedAlgorithmNode.cc | 62 ++-- .../DistributedAlgorithmNode.h | 129 ++++---- .../LeadershipBroker.cc | 36 +-- .../LeadershipBroker.h | 50 ++- src/distributed_algorithm_node/Message.cc | 14 +- src/distributed_algorithm_node/Message.h | 60 ++-- .../MessageBroker.cc | 199 ++++++------ .../MessageBroker.h | 254 ++++++++------- src/docker/Dockerfile | 2 +- src/hasher/expression_hasher.cc | 27 +- src/hasher/expression_hasher.h | 12 +- .../atom_db_publicist.h | 10 +- src/hyperon_das_atomdb_cpp/bind_helpers.h | 35 ++- .../hyperon_das_atomdb_cpp_bind.cc | 34 +- src/hyperon_das_atomdb_cpp_lib/database.cc | 6 +- src/hyperon_das_atomdb_cpp_lib/database.h | 190 +++++++----- .../document_types.h | 167 +++++----- src/hyperon_das_atomdb_cpp_lib/exceptions.h | 42 +-- .../expression_hasher.h | 57 ++-- src/hyperon_das_atomdb_cpp_lib/patterns.h | 27 +- src/hyperon_das_atomdb_cpp_lib/ram_only.cc | 6 +- src/hyperon_das_atomdb_cpp_lib/ram_only.h | 98 +++--- src/hyperon_das_atomdb_cpp_lib/type_aliases.h | 32 +- src/hyperon_das_node/hyperon_das_node_ext.cc | 140 ++++----- src/inference_agent/inference_agent.h | 15 +- src/inference_agent/inference_node.h | 4 - src/inference_agent/inference_request.h | 2 - .../das_link_creation_node.cc | 10 +- .../das_link_creation_node.h | 5 +- src/link_creation_agent/link.cc | 5 +- src/link_creation_agent/link.h | 95 +++--- .../link_create_template.h | 22 +- src/link_creation_agent/link_creation_agent.h | 30 +- src/link_creation_agent/queue.h | 16 +- src/main/attention_broker_main.cc | 20 +- src/main/inference_agent_main.cc | 1 - src/main/link_creation_agent_client_main.cc | 1 - src/main/link_creation_agent_main.cc | 27 +- src/main/link_creation_engine_main.cc | 119 ++++--- src/main/query_client_main.cc | 23 +- src/main/query_engine_main.cc | 13 +- src/main/word_query_main.cc | 79 +++-- src/query_engine/AtomDB.cc | 73 +++-- src/query_engine/AtomDB.h | 58 ++-- src/query_engine/AtomDBAPITypes.cc | 69 +++-- src/query_engine/AtomDBAPITypes.h | 86 +++--- src/query_engine/AtomDBSingleton.cc | 14 +- src/query_engine/AtomDBSingleton.h | 18 +- src/query_engine/CountAnswer.h | 6 +- src/query_engine/DASNode.cc | 23 +- src/query_engine/HandlesAnswer.cc | 105 +++---- src/query_engine/HandlesAnswer.h | 272 ++++++++-------- src/query_engine/StarNode.cc | 21 +- src/query_engine/StarNode.h | 45 ++- .../answer_processor/AttentionBrokerUpdater.h | 18 +- src/query_engine/query_element/And.h | 116 +++---- src/query_engine/query_element/Iterator.cc | 27 +- src/query_engine/query_element/Iterator.h | 36 ++- src/query_engine/query_element/LinkTemplate.h | 40 ++- src/query_engine/query_element/Operator.h | 29 +- src/query_engine/query_element/Or.h | 88 +++--- .../query_element/QueryElement.cc | 3 +- src/query_engine/query_element/QueryElement.h | 107 ++++--- .../query_element/RemoteIterator.h | 56 ++-- src/query_engine/query_element/RemoteSink.h | 15 +- src/query_engine/query_element/Sink.cc | 10 +- src/query_engine/query_element/Sink.h | 56 ++-- src/query_engine/query_element/Source.h | 20 +- src/query_engine/query_element/Terminal.h | 88 +++--- src/scripts/bazel.sh | 24 +- src/scripts/build.sh | 24 +- src/tests/cpp/and_operator_test.cc | 153 +++++---- src/tests/cpp/attention_broker_server_test.cc | 22 +- src/tests/cpp/das_node_test.cc | 126 ++++---- .../cpp/distributed_algorithm_node_test.cc | 96 ++---- src/tests/cpp/handle_trie_test.cc | 292 +++++++++--------- src/tests/cpp/handles_answer_test.cc | 14 +- src/tests/cpp/hebbian_network_test.cc | 50 ++- src/tests/cpp/hebbian_network_updater_test.cc | 22 +- src/tests/cpp/iterator_test.cc | 32 +- src/tests/cpp/leadership_broker_test.cc | 9 +- src/tests/cpp/link_creation_agent_test.cc | 52 ++-- src/tests/cpp/link_template_test.cc | 21 +- src/tests/cpp/message_broker_test.cc | 25 +- src/tests/cpp/nested_link_template_test.cc | 20 +- src/tests/cpp/query_node_test.cc | 32 +- src/tests/cpp/request_selector_test.cc | 36 +-- src/tests/cpp/shared_queue_test.cc | 87 +++--- src/tests/cpp/stimulus_spreader_test.cc | 67 ++-- src/tests/cpp/test_utils.cc | 26 +- src/tests/cpp/test_utils.h | 7 +- src/tests/cpp/worker_threads_test.cc | 65 ++-- src/tools/format/BUILD.bazel | 9 +- src/tools/lint/BUILD | 14 + src/tools/lint/linters.bzl | 11 + 119 files changed, 3545 insertions(+), 3325 deletions(-) create mode 100644 src/.clang-format diff --git a/.clang-format b/.clang-format index eac44b1..cb6fd0c 100644 --- a/.clang-format +++ b/.clang-format @@ -212,9 +212,9 @@ StatementAttributeLikeMacros: StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION -TabWidth: 4 +TabWidth: 8 UseCRLF: false -UseTab: Never +UseTab: Always WhitespaceSensitiveMacros: - STRINGIZE - PP_STRINGIZE diff --git a/src/.aspect/cli/config.yaml b/src/.aspect/cli/config.yaml index 642f7cc..5e360bc 100644 --- a/src/.aspect/cli/config.yaml +++ b/src/.aspect/cli/config.yaml @@ -1,3 +1,4 @@ lint: aspects: - //tools/lint:linters.bzl%ruff + # - //tools/lint:linters.bzl%clang_tidy diff --git a/src/.clang-format b/src/.clang-format new file mode 100644 index 0000000..eac44b1 --- /dev/null +++ b/src/.clang-format @@ -0,0 +1,225 @@ +--- +Language: Cpp +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 105 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: NextLine +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 3 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +PPIndentWidth: -1 +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: pb + BasedOnStyle: google +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Auto +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/src/BUILD b/src/BUILD index cd8de03..da79029 100644 --- a/src/BUILD +++ b/src/BUILD @@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"]) exports_files( [ ".ruff.toml", + ".clang-format" ], visibility = ["//visibility:public"], ) diff --git a/src/MODULE.bazel b/src/MODULE.bazel index 16ff9f1..2fe83bc 100644 --- a/src/MODULE.bazel +++ b/src/MODULE.bazel @@ -18,6 +18,19 @@ module(name = "das") # Bazel to run linters and formatters bazel_dep(name = "aspect_rules_lint", version = "1.2.0") +bazel_dep(name = "toolchains_llvm", version = "1.3.0") +bazel_dep(name = "bazel_skylib", version = "1.7.1") + + + +llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") +llvm.toolchain( + llvm_versions = { + "": "16.0.0", + "darwin-x86_64": "15.0.7", + }, +) +use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm") # C++ diff --git a/src/MODULE.bazel.lock b/src/MODULE.bazel.lock index e3f3c94..5e86800 100644 --- a/src/MODULE.bazel.lock +++ b/src/MODULE.bazel.lock @@ -303,6 +303,8 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/source.json": "32bd87e5f4d7acc57c5b2ff7c325ae3061d5e242c0c4c214ae87e0f1c13e54cb", + "https://bcr.bazel.build/modules/toolchains_llvm/1.3.0/MODULE.bazel": "6e02731e51f7eb2ec4b01c5e79e722bf738a631f6e03d9b4917cbf2cb027bee1", + "https://bcr.bazel.build/modules/toolchains_llvm/1.3.0/source.json": "4ce0373a89c6df34dd37cd67285bb871d8e225d30dcb67dd093e077a04bbbb71", "https://bcr.bazel.build/modules/toolchains_protoc/0.2.1/MODULE.bazel": "2f08433ff5e659069b3a1abfee2377d68f510f2de1da50678ed992c455b4ff91", "https://bcr.bazel.build/modules/toolchains_protoc/0.2.1/source.json": "4ee6b007b62e1b9e493b00ccc60e61a258633f304b74813b6e7f7234927be94c", "https://bcr.bazel.build/modules/upb/0.0.0-20211020-160625a/MODULE.bazel": "6cced416be2dc5b9c05efd5b997049ba795e5e4e6fafbe1624f4587767638928", @@ -7016,6 +7018,87 @@ ] } }, + "@@toolchains_llvm+//toolchain/extensions:llvm.bzl%llvm": { + "general": { + "bzlTransitiveDigest": "2eLMaPh4QKrn3wPljYBu5jSkkp9DfCf4yGKTR9lBN3c=", + "usagesDigest": "IzLZJo6jscH0wDdOUqR2z5ZKOHfkhS4PKLUmCbhjU2I=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "llvm_toolchain_llvm": { + "repoRuleId": "@@toolchains_llvm+//toolchain:rules.bzl%llvm", + "attributes": { + "alternative_llvm_sources": [], + "auth_patterns": {}, + "distribution": "auto", + "exec_arch": "", + "exec_os": "", + "libclang_rt": {}, + "llvm_mirror": "", + "llvm_version": "", + "llvm_versions": { + "": "16.0.0", + "darwin-x86_64": "15.0.7" + }, + "netrc": "", + "sha256": {}, + "strip_prefix": {}, + "urls": {} + } + }, + "llvm_toolchain": { + "repoRuleId": "@@toolchains_llvm+//toolchain:rules.bzl%toolchain", + "attributes": { + "absolute_paths": false, + "archive_flags": {}, + "compile_flags": {}, + "conly_flags": {}, + "coverage_compile_flags": {}, + "coverage_link_flags": {}, + "cxx_builtin_include_directories": {}, + "cxx_flags": {}, + "cxx_standard": {}, + "dbg_compile_flags": {}, + "exec_arch": "", + "exec_os": "", + "extra_exec_compatible_with": {}, + "extra_target_compatible_with": {}, + "link_flags": {}, + "link_libs": {}, + "llvm_versions": { + "": "16.0.0", + "darwin-x86_64": "15.0.7" + }, + "opt_compile_flags": {}, + "opt_link_flags": {}, + "stdlib": {}, + "target_settings": {}, + "unfiltered_compile_flags": {}, + "toolchain_roots": {}, + "sysroot": {} + } + } + }, + "recordedRepoMappingEntries": [ + [ + "toolchains_llvm+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "toolchains_llvm+", + "bazel_tools", + "bazel_tools" + ], + [ + "toolchains_llvm+", + "toolchains_llvm", + "toolchains_llvm+" + ] + ] + } + }, "@@toolchains_protoc+//protoc:extensions.bzl%protoc": { "general": { "bzlTransitiveDigest": "HnmcD4ia7/1ZuQnymt4OGHXrW62MmIgwCtHByGQ7LQs=", diff --git a/src/attention_broker/AttentionBrokerServer.cc b/src/attention_broker/AttentionBrokerServer.cc index 9193c6b..9194679 100644 --- a/src/attention_broker/AttentionBrokerServer.cc +++ b/src/attention_broker/AttentionBrokerServer.cc @@ -1,25 +1,20 @@ -#include "RequestSelector.h" #include "AttentionBrokerServer.h" -using namespace attention_broker_server; +#include "RequestSelector.h" -const double AttentionBrokerServer::RENT_RATE; -const double AttentionBrokerServer::SPREADING_RATE_LOWERBOUND; -const double AttentionBrokerServer::SPREADING_RATE_UPPERBOUND; +using namespace attention_broker_server; // -------------------------------------------------------------------------------- // Public methods - -AttentionBrokerServer::AttentionBrokerServer() { - this->global_context = "global"; - this->stimulus_requests = new SharedQueue(); - this->correlation_requests = new SharedQueue(); - this->worker_threads = new WorkerThreads(stimulus_requests, correlation_requests); - HebbianNetwork *network = new HebbianNetwork(); - this->hebbian_network[this->global_context] = network; - this->updater = HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); - this->stimulus_spreader = StimulusSpreader::factory(StimulusSpreaderType::TOKEN); +AttentionBrokerServer::AttentionBrokerServer() + : stimulus_requests(new SharedQueue()), + correlation_requests(new SharedQueue()), + worker_threads(new WorkerThreads(stimulus_requests, correlation_requests)), + updater(HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT)), + stimulus_spreader(StimulusSpreader::factory(StimulusSpreaderType::TOKEN)) { + auto* network = new HebbianNetwork(); + this->hebbian_network[this->global_context] = network; } AttentionBrokerServer::~AttentionBrokerServer() { @@ -29,7 +24,7 @@ AttentionBrokerServer::~AttentionBrokerServer() { delete this->correlation_requests; delete this->updater; delete this->stimulus_spreader; - for (auto pair:this->hebbian_network) { + for (const auto& pair : this->hebbian_network) { delete pair.second; } } @@ -41,24 +36,28 @@ void AttentionBrokerServer::graceful_shutdown() { // RPC API -Status AttentionBrokerServer::ping(ServerContext* grpc_context, const dasproto::Empty *request, dasproto::Ack* reply) { +Status AttentionBrokerServer::ping(ServerContext* /*grpc_context*/, + const dasproto::Empty* /*request*/, + dasproto::Ack* reply) { reply->set_msg("PING"); if (rpc_api_enabled) { return Status::OK; - } else{ + } else { return Status::CANCELLED; } } -Status AttentionBrokerServer::stimulate(ServerContext* grpc_context, const dasproto::HandleCount *request, dasproto::Ack* reply) { +Status AttentionBrokerServer::stimulate(ServerContext* /*grpc_context*/, + const dasproto::HandleCount* request, + dasproto::Ack* reply) { #ifdef DEBUG cout << "AttentionBrokerServer::stimulate() BEGIN" << endl; cout << "Context: " << request->context() << endl; #endif if (request->map_size() > 0) { - HebbianNetwork *network = select_hebbian_network(request->context()); - ((dasproto::HandleCount *) request)->set_hebbian_network((long) network); - //this->stimulus_requests->enqueue((void *) request); + HebbianNetwork* network = select_hebbian_network(request->context()); + ((dasproto::HandleCount*) request)->set_hebbian_network((long) network); + // this->stimulus_requests->enqueue((void *) request); this->stimulus_spreader->spread_stimuli(request); } reply->set_msg("STIMULATE"); @@ -67,20 +66,22 @@ Status AttentionBrokerServer::stimulate(ServerContext* grpc_context, const daspr #endif if (rpc_api_enabled) { return Status::OK; - } else{ + } else { return Status::CANCELLED; } } -Status AttentionBrokerServer::correlate(ServerContext* grpc_context, const dasproto::HandleList *request, dasproto::Ack* reply) { +Status AttentionBrokerServer::correlate(ServerContext* /*grpc_context*/, + const dasproto::HandleList* request, + dasproto::Ack* reply) { #ifdef DEBUG cout << "AttentionBrokerServer::correlate() BEGIN" << endl; cout << "Context: " << request->context() << endl; #endif if (request->list_size() > 0) { - HebbianNetwork *network = select_hebbian_network(request->context()); - ((dasproto::HandleList *) request)->set_hebbian_network((long) network); - //this->correlation_requests->enqueue((void *) request); + HebbianNetwork* network = select_hebbian_network(request->context()); + ((dasproto::HandleList*) request)->set_hebbian_network((long) network); + // this->correlation_requests->enqueue((void *) request); this->updater->correlation(request); } reply->set_msg("CORRELATE"); @@ -94,17 +95,19 @@ Status AttentionBrokerServer::correlate(ServerContext* grpc_context, const daspr } } -Status AttentionBrokerServer::get_importance(ServerContext *grpc_context, const dasproto::HandleList *request, dasproto::ImportanceList *reply) { +Status AttentionBrokerServer::get_importance(ServerContext* /*grpc_context*/, + const dasproto::HandleList* request, + dasproto::ImportanceList* reply) { #ifdef DEBUG cout << "AttentionBrokerServer::get_importance() BEGIN" << endl; cout << "Context: " << request->context() << endl; #endif if (this->rpc_api_enabled) { - int num_handles = request->list_size(); + int const num_handles = request->list_size(); if (num_handles > 0) { - HebbianNetwork *network = select_hebbian_network(request->context()); + HebbianNetwork* network = select_hebbian_network(request->context()); for (int i = 0; i < num_handles; i++) { - float importance = network->get_node_importance(request->list(i)); + float const importance = network->get_node_importance(request->list(i)); reply->add_list(importance); } } @@ -121,12 +124,12 @@ Status AttentionBrokerServer::get_importance(ServerContext *grpc_context, const // Private methods // -HebbianNetwork *AttentionBrokerServer::select_hebbian_network(const string &context) { - HebbianNetwork *network; - if ((context != "") && (this->hebbian_network.find(context) != this->hebbian_network.end())) { +HebbianNetwork* AttentionBrokerServer::select_hebbian_network(const string& context) { + HebbianNetwork* network = nullptr; + if ((!context.empty()) && (this->hebbian_network.find(context) != this->hebbian_network.end())) { network = this->hebbian_network[context]; } - if (context == "") { + if (context.empty()) { network = this->hebbian_network[this->global_context]; } else { if (this->hebbian_network.find(context) == this->hebbian_network.end()) { diff --git a/src/attention_broker/AttentionBrokerServer.h b/src/attention_broker/AttentionBrokerServer.h index 8269559..95e578b 100644 --- a/src/attention_broker/AttentionBrokerServer.h +++ b/src/attention_broker/AttentionBrokerServer.h @@ -5,18 +5,19 @@ #include #include -#include "attention_broker.grpc.pb.h" -#include "SharedQueue.h" -#include "WorkerThreads.h" + #include "HebbianNetwork.h" #include "HebbianNetworkUpdater.h" +#include "SharedQueue.h" #include "StimulusSpreader.h" +#include "WorkerThreads.h" +#include "attention_broker.grpc.pb.h" +using dasproto::AttentionBroker; using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::Status; -using dasproto::AttentionBroker; namespace attention_broker_server { @@ -29,122 +30,137 @@ namespace attention_broker_server { * Some parameters related to the stimulus spreading algorithms are also * stored in this class as static fields. Detailed description of them are * provided in StimulsSpreader. They are defined here because we may want - * to allow them to be modified by some homeostasis process running independently - * from StimulusSpreading. + * to allow them to be modified by some homeostasis process running + * independently from StimulusSpreading. */ -class AttentionBrokerServer final: public AttentionBroker::Service { - - public: - - /** - * Basic no-parameters constructor. - * Creates and initializes two request queues. One for stimuli spreading and - * another one for atom correlation. Worker threads to process such queues are - * also created inside a WorkerThread object. - * - * Different contexts are represented using different HebianNetwork objects. New - * contexts are created by caller's request but a default GLOBAL context is created - * here to be used whenever the caller don't specify a context. - */ - AttentionBrokerServer(); - - /** - * Destructor. - * - * Gracefully shutdown the GRPC server by stopping accepting new requests (any new request - * received after starting a shutdown process is denied and an error is returned to the - * caller) and waiting for all requests currently in the queues to be processed. Once all - * queues are empty, all worker threads are stopped and the queues and all other state structures - * are destroyed. - */ - ~AttentionBrokerServer(); - - static const unsigned int WORKER_THREADS_COUNT = 10; /// Number of working threads. - - - // Stimuli spreading parameters - string global_context; - constexpr const static double RENT_RATE = 0.50; /// double in [0..1] range. - constexpr const static double SPREADING_RATE_LOWERBOUND = 0.01; /// double in [0..1] range. - constexpr const static double SPREADING_RATE_UPPERBOUND = 0.10; /// double in [0..1] range. - - // RPC API - - /** - * Used by caller to check if AttentionBroker is running. - * - * @param grpc_context GRPC context object. - * @param request Empty request. - * @param reply The message which will be send back to the caller with a simple ACK. - * - * @return GRPC status OK if request were properly processed or CANCELLED otherwise. - */ - Status ping(ServerContext *grpc_context, const dasproto::Empty *request, dasproto::Ack *reply) override; - - /** - * Spread stimuli according to the passed request. - * - * Boost importance of passed atoms and run one cycle of stimuli spreading. The algorithm is explained - * in StimulusSpreader. - * - * @param grpc_context GRPC context object. - * @param request The request contains a list of handles of the atoms which should have the boost in - * importance as well as an associated integer indicating the proportion in which the boost should - * happen related to the other atoms in the same request. - * @param reply The message which will be send back to the caller with a simple ACK. - * - * @return GRPC status OK if request were properly processed or CANCELLED otherwise. - */ - Status stimulate(ServerContext *grpc_context, const dasproto::HandleCount *request, dasproto::Ack *reply) override; - - /** - * Correlates atoms passed in the request. - * - * @param grpc_context GRPC context object. - * @param request The request contains a list of handles of the atoms which should be correlated. - * @param reply The message which will be send back to the caller with a simple ACK. - * - * @return GRPC status OK if request were properly processed or CANCELLED otherwise. - */ - Status correlate(ServerContext* grpc_context, const dasproto::HandleList* request, dasproto::Ack* reply) override; - - /** - * Return importance of atoms passed in the request. - * - * - * @param grpc_context GRPC context object. - * @param request The request contains a list of handles of the atoms whose importrance are to be returned. - * @param reply A list with importance of atoms IN THE SAME ORDER they appear in the request. - * - * @return GRPC status OK if request were properly processed or CANCELLED otherwise. - */ - Status get_importance(ServerContext *grpc_context, const dasproto::HandleList *request, dasproto::ImportanceList *reply) override; - - // Other public methods - - /** - * Gracefully stop this GRPC server. - * - * Gracefully shutdown the GRPC server by stopping accepting new requests (any new request - * received after starting a shutdown process is denied and an error is returned to the - * caller) and waiting for all requests currently in the queues to be processed. - */ - void graceful_shutdown(); /// Gracefully stop this GRPC server. - - private: - - bool rpc_api_enabled = true; - SharedQueue *stimulus_requests; - SharedQueue *correlation_requests; - WorkerThreads *worker_threads; - unordered_map hebbian_network; - HebbianNetworkUpdater *updater; - StimulusSpreader *stimulus_spreader; - - - HebbianNetwork *select_hebbian_network(const string &context); +class AttentionBrokerServer final : public AttentionBroker::Service { + public: + /** + * Basic no-parameters constructor. + * Creates and initializes two request queues. One for stimuli spreading and + * another one for atom correlation. Worker threads to process such queues are + * also created inside a WorkerThread object. + * + * Different contexts are represented using different HebianNetwork objects. + * New contexts are created by caller's request but a default GLOBAL context + * is created here to be used whenever the caller don't specify a context. + */ + AttentionBrokerServer(); + + /** + * Destructor. + * + * Gracefully shutdown the GRPC server by stopping accepting new requests (any + * new request received after starting a shutdown process is denied and an + * error is returned to the caller) and waiting for all requests currently in + * the queues to be processed. Once all queues are empty, all worker threads + * are stopped and the queues and all other state structures are destroyed. + */ + ~AttentionBrokerServer(); + + static const unsigned int WORKER_THREADS_COUNT = 10; /// Number of working threads. + + // Stimuli spreading parameters + string global_context; + constexpr const static double RENT_RATE = 0.50; /// double in [0..1] range. + constexpr const static double SPREADING_RATE_LOWERBOUND = 0.01; /// double in [0..1] range. + constexpr const static double SPREADING_RATE_UPPERBOUND = 0.10; /// double in [0..1] range. + + // RPC API + + /** + * Used by caller to check if AttentionBroker is running. + * + * @param grpc_context GRPC context object. + * @param request Empty request. + * @param reply The message which will be send back to the caller with a + * simple ACK. + * + * @return GRPC status OK if request were properly processed or CANCELLED + * otherwise. + */ + Status ping(ServerContext* grpc_context, + const dasproto::Empty* request, + dasproto::Ack* reply) override; + + /** + * Spread stimuli according to the passed request. + * + * Boost importance of passed atoms and run one cycle of stimuli spreading. + * The algorithm is explained in StimulusSpreader. + * + * @param grpc_context GRPC context object. + * @param request The request contains a list of handles of the atoms which + * should have the boost in importance as well as an associated integer + * indicating the proportion in which the boost should happen related to the + * other atoms in the same request. + * @param reply The message which will be send back to the caller with a + * simple ACK. + * + * @return GRPC status OK if request were properly processed or CANCELLED + * otherwise. + */ + Status stimulate(ServerContext* grpc_context, + const dasproto::HandleCount* request, + dasproto::Ack* reply) override; + + /** + * Correlates atoms passed in the request. + * + * @param grpc_context GRPC context object. + * @param request The request contains a list of handles of the atoms which + * should be correlated. + * @param reply The message which will be send back to the caller with a + * simple ACK. + * + * @return GRPC status OK if request were properly processed or CANCELLED + * otherwise. + */ + Status correlate(ServerContext* grpc_context, + const dasproto::HandleList* request, + dasproto::Ack* reply) override; + + /** + * Return importance of atoms passed in the request. + * + * + * @param grpc_context GRPC context object. + * @param request The request contains a list of handles of the atoms whose + * importrance are to be returned. + * @param reply A list with importance of atoms IN THE SAME ORDER they appear + * in the request. + * + * @return GRPC status OK if request were properly processed or CANCELLED + * otherwise. + */ + Status get_importance(ServerContext* grpc_context, + const dasproto::HandleList* request, + dasproto::ImportanceList* reply) override; + + // Other public methods + + /** + * Gracefully stop this GRPC server. + * + * Gracefully shutdown the GRPC server by stopping accepting new requests (any + * new request received after starting a shutdown process is denied and an + * error is returned to the caller) and waiting for all requests currently in + * the queues to be processed. + */ + void graceful_shutdown(); /// Gracefully stop this GRPC server. + + private: + bool rpc_api_enabled = true; + SharedQueue* stimulus_requests; + SharedQueue* correlation_requests; + WorkerThreads* worker_threads; + unordered_map hebbian_network; + HebbianNetworkUpdater* updater; + StimulusSpreader* stimulus_spreader; + + HebbianNetwork* select_hebbian_network(const string& context); }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_ATTENTIONBROKERSERVER_H +#endif // _ATTENTION_BROKER_SERVER_ATTENTIONBROKERSERVER_H diff --git a/src/attention_broker/HandleTrie.cc b/src/attention_broker/HandleTrie.cc index b0ca670..4121171 100644 --- a/src/attention_broker/HandleTrie.cc +++ b/src/attention_broker/HandleTrie.cc @@ -1,24 +1,23 @@ -#include "Utils.h" -#include "expression_hasher.h" #include "HandleTrie.h" + #include #include +#include "Utils.h" +#include "expression_hasher.h" + using namespace attention_broker_server; using namespace commons; -HandleTrie::TrieValue::TrieValue() { -} +HandleTrie::TrieValue::TrieValue() = default; -HandleTrie::TrieValue::~TrieValue() { -} +HandleTrie::TrieValue::~TrieValue() = default; -HandleTrie::TrieNode::TrieNode() { - children = new TrieNode*[TRIE_ALPHABET_SIZE]; +HandleTrie::TrieNode::TrieNode() : children(new TrieNode*[TRIE_ALPHABET_SIZE]) { for (unsigned int i = 0; i < TRIE_ALPHABET_SIZE; i++) { - children[i] = NULL; + children[i] = nullptr; } - this->value = NULL; + this->value = nullptr; this->suffix_start = 0; } @@ -26,13 +25,11 @@ HandleTrie::TrieNode::~TrieNode() { for (unsigned int i = 0; i < TRIE_ALPHABET_SIZE; i++) { delete children[i]; } - delete [] children; + delete[] children; delete value; } -string HandleTrie::TrieValue::to_string() { - return ""; -} +string HandleTrie::TrieValue::to_string() { return ""; } bool HandleTrie::TLB_INITIALIZED = false; unsigned char HandleTrie::TLB[256]; @@ -40,23 +37,22 @@ unsigned char HandleTrie::TLB[256]; // -------------------------------------------------------------------------------- // Public methods - -string HandleTrie::TrieNode::to_string() { +string HandleTrie::TrieNode::to_string() const { string answer; if (suffix_start == 0) { answer = "''"; } else { - int n = suffix.size() - suffix_start; + int const n = suffix.size() - suffix_start; answer = suffix.substr(0, suffix_start) + "." + suffix.substr(suffix_start, n); } answer += " ["; for (unsigned int i = 0; i < TRIE_ALPHABET_SIZE; i++) { - if (children[i] != NULL) { + if (children[i] != nullptr) { answer += ("*"); } } answer += "] "; - if (value != NULL) { + if (value != nullptr) { answer += value->to_string(); } return answer; @@ -67,33 +63,30 @@ HandleTrie::HandleTrie(unsigned int key_size) { Utils::error("Invalid key size: " + to_string(key_size)); } this->key_size = key_size; - if (! HandleTrie::TLB_INITIALIZED) { + if (!HandleTrie::TLB_INITIALIZED) { HandleTrie::TLB_INIT(); } root = new TrieNode(); } -HandleTrie::~HandleTrie() { - delete root; -} - -HandleTrie::TrieValue *HandleTrie::insert(const string &key, TrieValue *value) { +HandleTrie::~HandleTrie() { delete root; } +HandleTrie::TrieValue* HandleTrie::insert(const string& key, TrieValue* value) const { if (key.size() != key_size) { Utils::error("Invalid key size: " + to_string(key.size()) + " != " + to_string(key_size)); } - TrieNode *tree_cursor = root; - TrieNode *parent = root; - TrieNode *child; - TrieNode *split; + TrieNode* tree_cursor = root; + TrieNode* parent = root; + TrieNode* child = nullptr; + TrieNode* split = nullptr; unsigned char key_cursor = 0; tree_cursor->trie_node_mutex.lock(); while (true) { - unsigned char c = TLB[(unsigned char) key[key_cursor]]; - if (tree_cursor->children[c] == NULL) { + unsigned char const c = TLB[(unsigned char) key[key_cursor]]; + if (tree_cursor->children[c] == nullptr) { if (tree_cursor->suffix_start > 0) { - unsigned char c_key_pred = TLB[(unsigned char) key[key_cursor -1]]; + unsigned char const c_key_pred = TLB[(unsigned char) key[key_cursor - 1]]; if (key[key_cursor] == tree_cursor->suffix[key_cursor]) { child = new TrieNode(); child->trie_node_mutex.lock(); @@ -108,7 +101,8 @@ HandleTrie::TrieValue *HandleTrie::insert(const string &key, TrieValue *value) { child->suffix = key; child->suffix_start = key_cursor + 1; child->value = value; - unsigned char c_tree_cursor = TLB[(unsigned char) tree_cursor->suffix[tree_cursor->suffix_start]]; + unsigned char const c_tree_cursor = + TLB[(unsigned char) tree_cursor->suffix[tree_cursor->suffix_start]]; tree_cursor->suffix_start++; split = new TrieNode(); split->children[c] = child; @@ -141,7 +135,7 @@ HandleTrie::TrieValue *HandleTrie::insert(const string &key, TrieValue *value) { tree_cursor->trie_node_mutex.lock(); if (tree_cursor->suffix_start > 0) { bool match = true; - unsigned int n = key.size(); + unsigned int const n = key.size(); for (unsigned int i = key_cursor; i < n; i++) { if (key[i] != tree_cursor->suffix[i]) { match = false; @@ -163,20 +157,19 @@ HandleTrie::TrieValue *HandleTrie::insert(const string &key, TrieValue *value) { } } -HandleTrie::TrieValue *HandleTrie::lookup(const string &key) { - +HandleTrie::TrieValue* HandleTrie::lookup(const string& key) const { if (key.size() != key_size) { Utils::error("Invalid key size: " + to_string(key.size()) + " != " + to_string(key_size)); } - TrieNode *tree_cursor = root; - TrieValue *value; + TrieNode* tree_cursor = root; + TrieValue* value = nullptr; unsigned char key_cursor = 0; tree_cursor->trie_node_mutex.lock(); - while (tree_cursor != NULL) { + while (tree_cursor != nullptr) { if (tree_cursor->suffix_start > 0) { bool match = true; - unsigned int n = key.size(); + unsigned int const n = key.size(); for (unsigned int i = key_cursor; i < n; i++) { if (key[i] != tree_cursor->suffix[i]) { match = false; @@ -186,31 +179,32 @@ HandleTrie::TrieValue *HandleTrie::lookup(const string &key) { if (match) { value = tree_cursor->value; } else { - value = NULL; + value = nullptr; } tree_cursor->trie_node_mutex.unlock(); return value; } else { - unsigned char c = TLB[(unsigned char) key[key_cursor]]; - TrieNode *child = tree_cursor->children[c]; + unsigned char const c = TLB[(unsigned char) key[key_cursor]]; + TrieNode* child = tree_cursor->children[c]; tree_cursor->trie_node_mutex.unlock(); tree_cursor = child; key_cursor++; - if (tree_cursor != NULL) { + if (tree_cursor != nullptr) { tree_cursor->trie_node_mutex.lock(); } } } - return NULL; + return nullptr; } -void HandleTrie::traverse(bool keep_root_locked, bool (*visit_function)(TrieNode *node, void *data), void *data) { - - stack node_stack; - TrieNode *cursor; +void HandleTrie::traverse(bool keep_root_locked, + bool (*visit_function)(TrieNode* node, void* data), + void* data) const { + stack node_stack; + TrieNode* cursor = nullptr; node_stack.push(root); - while (! node_stack.empty()) { + while (!node_stack.empty()) { cursor = node_stack.top(); node_stack.pop(); cursor->trie_node_mutex.lock(); @@ -223,8 +217,8 @@ void HandleTrie::traverse(bool keep_root_locked, bool (*visit_function)(TrieNode return; } } else { - for (unsigned int i = TRIE_ALPHABET_SIZE - 1; ; i--) { - if (cursor->children[i] != NULL) { + for (unsigned int i = TRIE_ALPHABET_SIZE - 1;; i--) { + if (cursor->children[i] != nullptr) { node_stack.push(cursor->children[i]); } if (i == 0) { @@ -232,7 +226,7 @@ void HandleTrie::traverse(bool keep_root_locked, bool (*visit_function)(TrieNode } } } - if ((! keep_root_locked) || (cursor != root)) { + if ((!keep_root_locked) || (cursor != root)) { cursor->trie_node_mutex.unlock(); } } diff --git a/src/attention_broker/HandleTrie.h b/src/attention_broker/HandleTrie.h index 34e2c97..861c1bc 100644 --- a/src/attention_broker/HandleTrie.h +++ b/src/attention_broker/HandleTrie.h @@ -13,82 +13,85 @@ namespace attention_broker_server { /** * Data abstraction implementing a map handle->value using a trie (prefix tree). * - * This data structure is basicaly like a hashmap mapping from handles to objects of - * type HandleTrie::TrieValue. + * This data structure is basicaly like a hashmap mapping from handles to + * objects of type HandleTrie::TrieValue. * - * When a (key, value) pair is inserted and key is already present, the method merge() - * in value is called passing the newly inserted value. + * When a (key, value) pair is inserted and key is already present, the method + * merge() in value is called passing the newly inserted value. */ class HandleTrie { - -public: - + public: /** * Virtual basic class to be extended by objects used as "values". */ class TrieValue { - protected: - TrieValue(); /// basic empty constructor. - public: - virtual ~TrieValue(); /// Destructor. - virtual void merge(TrieValue *other) = 0; /// Called when a repeated handle is inserted. - virtual string to_string(); /// Returns a string representation of the value object. - + protected: + TrieValue(); /// basic empty constructor. + public: + virtual ~TrieValue(); /// Destructor. + virtual void merge(TrieValue* other) = 0; /// Called when a repeated handle is inserted. + virtual string to_string(); /// Returns a string representation of the value object. }; /** * A node in the prefix tree used to store keys. */ class TrieNode { - public: - TrieNode(); /// Basic empty constructor. - ~TrieNode(); /// Destructor. - - TrieNode **children; /// Array with children of this node. - TrieValue *value; /// Value attached to this node or NULL if none. - string suffix; /// The key (handle) attached to this node (leafs) or NULL if none (internal nodes). - unsigned char suffix_start; /// The point in the suffix from which this node (leaf) differs from its siblings. - mutex trie_node_mutex; - - string to_string(); /// Returns a string representation of this node. + public: + TrieNode(); /// Basic empty constructor. + ~TrieNode(); /// Destructor. + + TrieNode** children; /// Array with children of this node. + TrieValue* value; /// Value attached to this node or NULL if none. + string suffix; /// The key (handle) attached to this node (leafs) or NULL if + /// none (internal nodes). + unsigned char suffix_start; /// The point in the suffix from which this node + /// (leaf) differs from its siblings. + mutex trie_node_mutex; + + string to_string(); /// Returns a string representation of this node. }; - HandleTrie(unsigned int key_size); /// Basic constructor. - ~HandleTrie(); /// Destructor. + HandleTrie(unsigned int key_size); /// Basic constructor. + ~HandleTrie(); /// Destructor. /** - * Insert a new key in this HandleTrie or merge its value if the key is already present. + * Insert a new key in this HandleTrie or merge its value if the key is + * already present. * * @param key Handle being inserted. * @param value HandleTrie::TrieValue object being inserted. * - * @return The resulting HandleTrie::TrieValue object after insertion (and eventually the merge) is processed. + * @return The resulting HandleTrie::TrieValue object after insertion (and + * eventually the merge) is processed. */ - TrieValue *insert(const string &key, TrieValue *value); + TrieValue* insert(const string& key, TrieValue* value); /** * Lookup for a given handle. * * @param key Handle being searched. * - * @return The HandleTrie::TrieValue object attached to the passed key or NULL if none. + * @return The HandleTrie::TrieValue object attached to the passed key or NULL + * if none. */ - TrieValue *lookup(const string &key); + TrieValue* lookup(const string& key); /** - * Traverse all keys (in-order) calling the passed visit_function once per stored value. + * Traverse all keys (in-order) calling the passed visit_function once per + * stored value. * - * @param keep_root_locked Keep root HandleTrie::TrieNode locked during the whole traversing - * releasing the lock when it ends. + * @param keep_root_locked Keep root HandleTrie::TrieNode locked during the + * whole traversing releasing the lock when it ends. * @param visit_function Function to be called when each value is visited. - * @param data Additional information passed to visit_function or NULL if none. + * @param data Additional information passed to visit_function or NULL if + * none. */ - void traverse(bool keep_root_locked, bool (*visit_function)(TrieNode *node, void *data), void *data); - - TrieNode *root; + void traverse(bool keep_root_locked, bool (*visit_function)(TrieNode* node, void* data), void* data); -private: + TrieNode* root; + private: static unsigned char TLB[256]; static bool TLB_INITIALIZED; static void TLB_INIT() { @@ -114,6 +117,6 @@ class HandleTrie { unsigned int key_size; }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_HANDLETRIE_H +#endif // _ATTENTION_BROKER_SERVER_HANDLETRIE_H diff --git a/src/attention_broker/HebbianNetwork.cc b/src/attention_broker/HebbianNetwork.cc index 62042f1..cacd3ca 100644 --- a/src/attention_broker/HebbianNetwork.cc +++ b/src/attention_broker/HebbianNetwork.cc @@ -1,6 +1,10 @@ +#include "HebbianNetwork.h" + +#include + #include #include -#include "HebbianNetwork.h" + #include "Utils.h" #include "expression_hasher.h" @@ -9,35 +13,33 @@ using namespace attention_broker_server; // -------------------------------------------------------------------------------- // Public methods -HebbianNetwork::HebbianNetwork() { - nodes = new HandleTrie(HANDLE_HASH_SIZE - 1); - largest_arity = 0; +HebbianNetwork::HebbianNetwork() : nodes(new HandleTrie(HANDLE_HASH_SIZE - 1)) { tokens_mutex.lock(); - tokens_to_distribute = 1.0; + tokens_mutex.unlock(); } -HebbianNetwork::~HebbianNetwork() { - delete nodes; -} +HebbianNetwork::~HebbianNetwork() { delete nodes; } string HebbianNetwork::Node::to_string() { - return "(" + std::to_string(count) + ", " + std::to_string(importance) + ", " + std::to_string(arity) + ")"; + return "(" + std::to_string(count) + ", " + std::to_string(importance) + ", " + + std::to_string(arity) + ")"; } -string HebbianNetwork::Edge::to_string() { - return "(" + std::to_string(count) + ")"; -} +string HebbianNetwork::Edge::to_string() { return "(" + std::to_string(count) + ")"; } -HebbianNetwork::Node *HebbianNetwork::add_node(string handle) { - return (Node *) nodes->insert(handle, new HebbianNetwork::Node()); +HebbianNetwork::Node* HebbianNetwork::add_node(const string& handle) { + return dynamic_cast(nodes->insert(handle, new HebbianNetwork::Node())); } -HebbianNetwork::Edge *HebbianNetwork::add_asymmetric_edge(string handle1, string handle2, Node *node1, Node *node2) { - if (node1 == NULL) { - node1 = (Node *) nodes->lookup(handle1); +HebbianNetwork::Edge* HebbianNetwork::add_asymmetric_edge(const string& handle1, + const string& handle2, + Node* node1, + Node* node2) { + if (node1 == nullptr) { + node1 = dynamic_cast(nodes->lookup(handle1)); } - Edge *edge = (Edge *) node1->neighbors->insert(handle2, new HebbianNetwork::Edge()); + Edge* edge = dynamic_cast(node1->neighbors->insert(handle2, new HebbianNetwork::Edge())); if (edge->count == 1) { // First time this edge is added edge->node1 = node1; @@ -52,38 +54,41 @@ HebbianNetwork::Edge *HebbianNetwork::add_asymmetric_edge(string handle1, string return edge; } -void HebbianNetwork::add_symmetric_edge(string handle1, string handle2, Node *node1, Node *node2) { +void HebbianNetwork::add_symmetric_edge(const string& handle1, + const string& handle2, + Node* node1, + Node* node2) { add_asymmetric_edge(handle1, handle2, node1, node2); add_asymmetric_edge(handle2, handle1, node2, node1); } -HebbianNetwork::Node *HebbianNetwork::lookup_node(string handle) { - return (Node *) nodes->lookup(handle); +HebbianNetwork::Node* HebbianNetwork::lookup_node(const string& handle) { + return dynamic_cast(nodes->lookup(handle)); } -unsigned int HebbianNetwork::get_node_count(string handle) { - Node *node = (Node *) nodes->lookup(handle); - if (node == NULL) { +unsigned int HebbianNetwork::get_node_count(const string& handle) { + Node* node = dynamic_cast(nodes->lookup(handle)); + if (node == nullptr) { return 0; } else { return node->count; } } -ImportanceType HebbianNetwork::get_node_importance(string handle) { - Node *node = (Node *) nodes->lookup(handle); - if (node == NULL) { +ImportanceType HebbianNetwork::get_node_importance(const string& handle) { + Node* node = dynamic_cast(nodes->lookup(handle)); + if (node == nullptr) { return 0; } else { return node->importance; } } -unsigned int HebbianNetwork::get_asymmetric_edge_count(string handle1, string handle2) { - Node *source = (Node *) nodes->lookup(handle1); - if (source != NULL) { - Edge *edge = (Edge *) source->neighbors->lookup(handle2); - if (edge != NULL) { +unsigned int HebbianNetwork::get_asymmetric_edge_count(const string& handle1, const string& handle2) { + Node* source = dynamic_cast(nodes->lookup(handle1)); + if (source != nullptr) { + Edge* edge = dynamic_cast(source->neighbors->lookup(handle2)); + if (edge != nullptr) { return edge->count; } } @@ -91,7 +96,7 @@ unsigned int HebbianNetwork::get_asymmetric_edge_count(string handle1, string ha } ImportanceType HebbianNetwork::alienate_tokens() { - ImportanceType answer; + ImportanceType answer = NAN; tokens_mutex.lock(); answer = tokens_to_distribute; tokens_to_distribute = 0.0; @@ -99,20 +104,16 @@ ImportanceType HebbianNetwork::alienate_tokens() { return answer; } -void HebbianNetwork::visit_nodes( - bool keep_root_locked, - bool (*visit_function)(HandleTrie::TrieNode *node, void *data), - void *data) { - +void HebbianNetwork::visit_nodes(bool keep_root_locked, + bool (*visit_function)(HandleTrie::TrieNode* node, void* data), + void* data) { nodes->traverse(keep_root_locked, visit_function, data); } -static inline void release_locks( - HandleTrie::TrieNode *root, - HandleTrie::TrieNode *cursor, - bool keep_root_locked, - bool release_root_after_end) { - +static inline void release_locks(HandleTrie::TrieNode* root, + HandleTrie::TrieNode* cursor, + bool keep_root_locked, + bool release_root_after_end) { if (keep_root_locked && release_root_after_end && (root != cursor)) { root->trie_node_mutex.unlock(); } diff --git a/src/attention_broker/HebbianNetwork.h b/src/attention_broker/HebbianNetwork.h index 37f8149..468ff4e 100644 --- a/src/attention_broker/HebbianNetwork.h +++ b/src/attention_broker/HebbianNetwork.h @@ -1,9 +1,10 @@ #ifndef _ATTENTION_BROKER_SERVER_HEBBIANNETWORK_H #define _ATTENTION_BROKER_SERVER_HEBBIANNETWORK_H -#include -#include #include +#include +#include + #include "HandleTrie.h" #include "expression_hasher.h" @@ -14,52 +15,53 @@ namespace attention_broker_server { typedef double ImportanceType; /** - * Data abstraction of an asymmetric Hebbian Network with only direct hebbian links. + * Data abstraction of an asymmetric Hebbian Network with only direct hebbian + * links. * - * A Hebbian Network, in the context of AttentionBrokerServer, is a directed graph with - * weights in the edges A->B representing the probability of B being present in a DAS - * query answer given that A is present. In other words, provided that the atom A is one of - * the atoms returned in a given query in DAS, the weight of the edge A->B in - * a HebbianNetwork is an estimate of the probability of B being present in the same answer. + * A Hebbian Network, in the context of AttentionBrokerServer, is a directed + * graph with weights in the edges A->B representing the probability of B being + * present in a DAS query answer given that A is present. In other words, + * provided that the atom A is one of the atoms returned in a given query in + * DAS, the weight of the edge A->B in a HebbianNetwork is an estimate of the + * probability of B being present in the same answer. * - * HebbianNetwork is asymmetric, meaning that the weight of A->B can be different from the - * weight of B->A. + * HebbianNetwork is asymmetric, meaning that the weight of A->B can be + * different from the weight of B->A. * - * All edges in HebbianNetwork are "direct" hebbian links meaning that they estimate the - * probability of B BEING present in a answer given that A is. There are no "reverse" - * hebbian links which would mean the probability of B being NOT present in an answer - * given that A is. + * All edges in HebbianNetwork are "direct" hebbian links meaning that they + * estimate the probability of B BEING present in a answer given that A is. + * There are no "reverse" hebbian links which would mean the probability of B + * being NOT present in an answer given that A is. * - * HebbianNetwork keeps nodes in a HandleTrie which is basically a data structure to map - * from handle to a value object (mostly like a hashmap but slightly more efficient because - * it makes the assumption that the key is a handle). So in the stored value object it stores - * another HandleTrie to keep track of the neighbors. So we have two types of value objects, - * one to represent Nodes and another one to represent Edges. + * HebbianNetwork keeps nodes in a HandleTrie which is basically a data + * structure to map from handle to a value object (mostly like a hashmap but + * slightly more efficient because it makes the assumption that the key is a + * handle). So in the stored value object it stores another HandleTrie to keep + * track of the neighbors. So we have two types of value objects, one to + * represent Nodes and another one to represent Edges. */ class HebbianNetwork { + public: + HebbianNetwork(); /// Basic constructor. + ~HebbianNetwork(); /// Destructor. -public: - - HebbianNetwork(); /// Basic constructor. - ~HebbianNetwork(); /// Destructor. - - unsigned int largest_arity; /// Largest arity among nodes in this network. + unsigned int largest_arity; /// Largest arity among nodes in this network. mutex largest_arity_mutex; - // Node and Link don't inherit from a common "Atom" class to avoid having virtual methods, - // which couldn't be properly inlined. + // Node and Link don't inherit from a common "Atom" class to avoid having + // virtual methods, which couldn't be properly inlined. /** * Node object used as the value in HandleTrie. */ - class Node: public HandleTrie::TrieValue { - public: - unsigned int arity; /// Number of neighbors of this Node. - unsigned int count; /// Count for this Node. - ImportanceType importance; /// Importance of this Node. - ImportanceType stimuli_to_spread; /// Amount of importance this node will spread in the next - /// stimuli spreading cycle. - HandleTrie *neighbors; // Neighbors of this Node. + class Node : public HandleTrie::TrieValue { + public: + unsigned int arity; /// Number of neighbors of this Node. + unsigned int count; /// Count for this Node. + ImportanceType importance; /// Importance of this Node. + ImportanceType stimuli_to_spread; /// Amount of importance this node will spread in the + /// next stimuli spreading cycle. + HandleTrie* neighbors; // Neighbors of this Node. Node() { arity = 0; count = 1; @@ -67,58 +69,58 @@ class HebbianNetwork { stimuli_to_spread = 0.0; neighbors = new HandleTrie(HANDLE_HASH_SIZE - 1); } - inline void merge(HandleTrie::TrieValue *other) { - count += ((Node *) other)->count; - importance += ((Node *) other)->importance; + inline void merge(HandleTrie::TrieValue* other) { + count += ((Node*) other)->count; + importance += ((Node*) other)->importance; } - string to_string(); /// String representation of this Node. + string to_string(); /// String representation of this Node. }; /** * Edge object used as the value in HandleTrie. */ - class Edge: public HandleTrie::TrieValue { - public: - unsigned int count; /// Count for this edge. - Node *node1; /// Source Node. - Node *node2; /// Target node. + class Edge : public HandleTrie::TrieValue { + public: + unsigned int count; /// Count for this edge. + Node* node1; /// Source Node. + Node* node2; /// Target node. Edge() { count = 1; node1 = node2 = NULL; } - inline void merge(HandleTrie::TrieValue *other) { - count += ((Edge *) other)->count; - } - string to_string(); /// String representation of this Edge. + inline void merge(HandleTrie::TrieValue* other) { count += ((Edge*) other)->count; } + string to_string(); /// String representation of this Edge. }; /** - * Adds a new node to this network or increase +1 to its count if it already exists. + * Adds a new node to this network or increase +1 to its count if it already + * exists. * * @param handle Atom being added. * * @return the value object attached to the node being inserted. */ - Node *add_node(string handle); + Node* add_node(string handle); /** - * Adds a new edge handle1->handle2 to this network or increase +1 to its count if it already exists. + * Adds a new edge handle1->handle2 to this network or increase +1 to its + * count if it already exists. * * @param handle1 Source of the edge. * @param handle2 Target of the edge. * * @return the value object attached to the edge being inserted. */ - Edge *add_asymmetric_edge(string handle1, string handle2, Node *node1, Node *node2); + Edge* add_asymmetric_edge(string handle1, string handle2, Node* node1, Node* node2); /** - * Adds new edges handle1->handle2 and handle2->handle1 to this network or increase +1 - * to their count if they already exist. + * Adds new edges handle1->handle2 and handle2->handle1 to this network or + * increase +1 to their count if they already exist. * * @param handle1 One of the nodes in the edge. * @param handle2 The other node in the edge. */ - void add_symmetric_edge(string handle1, string handle2, Node *node1, Node *node2); + void add_symmetric_edge(string handle1, string handle2, Node* node1, Node* node2); /** * Lookup and return the value attached to the passed handle. @@ -127,7 +129,7 @@ class HebbianNetwork { * * @return The value object attached to the node. */ - Node *lookup_node(string handle); + Node* lookup_node(string handle); /** * Lookup for the passed node and return its count. @@ -161,28 +163,27 @@ class HebbianNetwork { * Traverse the node's HandleTrie and call the passed function once for each * of the visited nodes. * - * @param keep_root_locked True iff HandleTrie root should be kept locked during - * all the traversal. If false, the root lock is freed just like any other internal - * trie node. - * @param visit_function Function to be called passing each visited node. This function + * @param keep_root_locked True iff HandleTrie root should be kept locked + * during all the traversal. If false, the root lock is freed just like any + * other internal trie node. + * @param visit_function Function to be called passing each visited node. This + * function * @param data Additional data to be passed to the visit_function. * * expects the Node and a pointer to eventual data used inside visit_function. */ - void visit_nodes( - bool keep_root_locked, - bool (*visit_function)(HandleTrie::TrieNode *node, void *data), - void *data); + void visit_nodes(bool keep_root_locked, + bool (*visit_function)(HandleTrie::TrieNode* node, void* data), + void* data); ImportanceType alienate_tokens(); -private: - - HandleTrie *nodes; + private: + HandleTrie* nodes; ImportanceType tokens_to_distribute; mutex tokens_mutex; }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_HEBBIANNETWORK_H +#endif // _ATTENTION_BROKER_SERVER_HEBBIANNETWORK_H diff --git a/src/attention_broker/HebbianNetworkUpdater.cc b/src/attention_broker/HebbianNetworkUpdater.cc index c9a954a..51699cf 100644 --- a/src/attention_broker/HebbianNetworkUpdater.cc +++ b/src/attention_broker/HebbianNetworkUpdater.cc @@ -1,50 +1,47 @@ -#include #include "HebbianNetworkUpdater.h" + +#include + #include "HebbianNetwork.h" #include "Utils.h" using namespace attention_broker_server; using namespace commons; -HebbianNetworkUpdater::HebbianNetworkUpdater() { -} +HebbianNetworkUpdater::HebbianNetworkUpdater() = default; // -------------------------------------------------------------------------------- // Public methods -HebbianNetworkUpdater::~HebbianNetworkUpdater() { -} +HebbianNetworkUpdater::~HebbianNetworkUpdater() = default; -HebbianNetworkUpdater *HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType instance_type) { +HebbianNetworkUpdater* HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType instance_type) { switch (instance_type) { - case HebbianNetworkUpdaterType:: EXACT_COUNT: { + case HebbianNetworkUpdaterType::EXACT_COUNT: { return new ExactCountHebbianUpdater(); } default: { Utils::error("Invalid HebbianNetworkUpdaterType: " + to_string((int) instance_type)); - return NULL; // to avoid warnings + return nullptr; // to avoid warnings } } - } -ExactCountHebbianUpdater::ExactCountHebbianUpdater() { -} +ExactCountHebbianUpdater::ExactCountHebbianUpdater() = default; -ExactCountHebbianUpdater::~ExactCountHebbianUpdater() { -} +ExactCountHebbianUpdater::~ExactCountHebbianUpdater() = default; -void ExactCountHebbianUpdater::correlation(const dasproto::HandleList *request) { - HebbianNetwork *network = (HebbianNetwork *) request->hebbian_network(); - if (network != NULL) { - for (const string &s: ((dasproto::HandleList *) request)->list()) { +void ExactCountHebbianUpdater::correlation(const dasproto::HandleList* request) { + auto* network = (HebbianNetwork*) request->hebbian_network(); + if (network != nullptr) { + for (const string& s : ((dasproto::HandleList*) request)->list()) { network->add_node(s); } - HebbianNetwork::Node *node1; - HebbianNetwork::Node *node2; - for (const string &s1: ((dasproto::HandleList *) request)->list()) { + HebbianNetwork::Node* node1 = nullptr; + HebbianNetwork::Node* node2 = nullptr; + for (const string& s1 : ((dasproto::HandleList*) request)->list()) { node1 = network->lookup_node(s1); - for (const string &s2: ((dasproto::HandleList *) request)->list()) { + for (const string& s2 : ((dasproto::HandleList*) request)->list()) { if (s1.compare(s2) < 0) { node2 = network->lookup_node(s2); network->add_symmetric_edge(s1, s2, node1, node2); diff --git a/src/attention_broker/HebbianNetworkUpdater.h b/src/attention_broker/HebbianNetworkUpdater.h index 3862052..1f6c056 100644 --- a/src/attention_broker/HebbianNetworkUpdater.h +++ b/src/attention_broker/HebbianNetworkUpdater.h @@ -11,91 +11,94 @@ namespace attention_broker_server { * Algorithm used to update HebbianNetwork weights in "correlate" requests. */ enum class HebbianNetworkUpdaterType { - EXACT_COUNT /// Tracks counts of nodes and links computing actual weights on demand. + EXACT_COUNT /// Tracks counts of nodes and links computing actual weights on + /// demand. }; /** - * Process correlation requests by changing the weights in the passed HebbianNetwork - * to reflect the evidence provided in the request. + * Process correlation requests by changing the weights in the passed + * HebbianNetwork to reflect the evidence provided in the request. * - * Objects of this class are used by worker threads to process "correlation" requests. + * Objects of this class are used by worker threads to process "correlation" + * requests. * - * The request have a list of handles of atoms which appeared together in the same query - * answer. So it's a positive evidence of correlation among such atoms. The HebbianNetwork - * weights are changed to reflect this evidence. + * The request have a list of handles of atoms which appeared together in the + * same query answer. So it's a positive evidence of correlation among such + * atoms. The HebbianNetwork weights are changed to reflect this evidence. * - * This is an abstract class. Concrete subclasses implement different ways of computing - * weights in HebbianNetwork. + * This is an abstract class. Concrete subclasses implement different ways of + * computing weights in HebbianNetwork. */ class HebbianNetworkUpdater { - -public: - + public: /** * Factory method. * - * Factory method to instantiate concrete subclasses according to the passed parameter. + * Factory method to instantiate concrete subclasses according to the passed + * parameter. * * @param instance_type Type of concrete subclass to be instantiated. * * @return An object of the passed type. */ - static HebbianNetworkUpdater *factory(HebbianNetworkUpdaterType instance_type); - virtual ~HebbianNetworkUpdater(); /// Destructor. + static HebbianNetworkUpdater* factory(HebbianNetworkUpdaterType instance_type); + virtual ~HebbianNetworkUpdater(); /// Destructor. /** * Process a correlation evidence. * - * The evidence is used to update the weights in the HebbianNetwork. The actual way these - * weights are updated depends on the type of the concrete subclass that implements this method. + * The evidence is used to update the weights in the HebbianNetwork. The + * actual way these weights are updated depends on the type of the concrete + * subclass that implements this method. * - * @param request A list of handles of atoms which appeared in the same query answer. + * @param request A list of handles of atoms which appeared in the same query + * answer. */ virtual void correlation(const dasproto::HandleList* request) = 0; -protected: - - HebbianNetworkUpdater(); /// Basic empty constructor. - -private: + protected: + HebbianNetworkUpdater(); /// Basic empty constructor. + private: }; /** - * Process correlation requests by changing the weights in the passed HebbianNetwork - * to reflect the evidence provided in the request. + * Process correlation requests by changing the weights in the passed + * HebbianNetwork to reflect the evidence provided in the request. * - * Objects of this class are used by worker threads to process "correlation" requests. + * Objects of this class are used by worker threads to process "correlation" + * requests. * - * The request have a list of handles of atoms which appeared together in the same query - * answer. So it's a positive evidence of correlation among such atoms. The HebbianNetwork - * weights are changed to reflect this evidence. + * The request have a list of handles of atoms which appeared together in the + * same query answer. So it's a positive evidence of correlation among such + * atoms. The HebbianNetwork weights are changed to reflect this evidence. * - * This HebbianNetworkUpdater keeps track of actual counts of atoms and symmetric hebbian - * links between them as they appear in correlation evidence (requests). Actual hebbian weights - * between A -> B are calculated on demand by dividing count(A->B) / count(A). + * This HebbianNetworkUpdater keeps track of actual counts of atoms and + * symmetric hebbian links between them as they appear in correlation evidence + * (requests). Actual hebbian weights between A -> B are calculated on demand by + * dividing count(A->B) / count(A). */ -class ExactCountHebbianUpdater: public HebbianNetworkUpdater { - -public: - - ExactCountHebbianUpdater(); /// Basic empty constructor. - ~ExactCountHebbianUpdater(); /// Destructor. +class ExactCountHebbianUpdater : public HebbianNetworkUpdater { + public: + ExactCountHebbianUpdater(); /// Basic empty constructor. + ~ExactCountHebbianUpdater(); /// Destructor. /** * Process a correlation evidence. * - * The evidence is used to update the weights in the HebbianNetwork. + * The evidence is used to update the weights in the HebbianNetwork. * - * This HebbianNetworkUpdater keeps track of actual counts of atoms and symmetric hebbian - * links between them as they appear in correlation evidence (requests). Actual hebbian weights - * between A -> B are calculated on demand by dividing count(A->B) / count(A). + * This HebbianNetworkUpdater keeps track of actual counts of atoms and + * symmetric hebbian links between them as they appear in correlation evidence + * (requests). Actual hebbian weights between A -> B are calculated on demand + * by dividing count(A->B) / count(A). * - * @param request A list of handles of atoms which appeared in the same query answer. + * @param request A list of handles of atoms which appeared in the same query + * answer. */ - void correlation(const dasproto::HandleList *request); /// Process a correlation evidence. + void correlation(const dasproto::HandleList* request); /// Process a correlation evidence. }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_HEBBIANNETWORKUPDATER_H +#endif // _ATTENTION_BROKER_SERVER_HEBBIANNETWORKUPDATER_H diff --git a/src/attention_broker/RequestSelector.cc b/src/attention_broker/RequestSelector.cc index e589de1..cf49734 100644 --- a/src/attention_broker/RequestSelector.cc +++ b/src/attention_broker/RequestSelector.cc @@ -1,61 +1,47 @@ #include "RequestSelector.h" -#include "Utils.h" + #include +#include "Utils.h" + using namespace attention_broker_server; // -------------------------------------------------------------------------------- // Public methods -RequestSelector::RequestSelector( - unsigned int thread_id, - SharedQueue *stimulus, - SharedQueue *correlation) { +RequestSelector::RequestSelector(unsigned int thread_id, SharedQueue* stimulus, SharedQueue* correlation) + : thread_id(thread_id), stimulus(stimulus), correlation(correlation) {} - this->thread_id = thread_id; - this->stimulus = stimulus; - this->correlation = correlation; -} +RequestSelector::~RequestSelector() = default; -RequestSelector::~RequestSelector() { -} - -EvenThreadCount::EvenThreadCount( - unsigned int thread_id, - SharedQueue *stimulus, - SharedQueue *correlation) : RequestSelector(thread_id, stimulus, correlation) { - - even_thread_id = ((thread_id % 2) == 0); -} - -EvenThreadCount::~EvenThreadCount() { -} +EvenThreadCount::EvenThreadCount(unsigned int thread_id, SharedQueue* stimulus, SharedQueue* correlation) + : RequestSelector(thread_id, stimulus, correlation), even_thread_id((thread_id % 2) == 0) {} -RequestSelector *RequestSelector::factory( - SelectorType instance_type, - unsigned int thread_id, - SharedQueue *stimulus, - SharedQueue *correlation) { +EvenThreadCount::~EvenThreadCount() = default; +RequestSelector* RequestSelector::factory(SelectorType instance_type, + unsigned int thread_id, + SharedQueue* stimulus, + SharedQueue* correlation) { switch (instance_type) { case SelectorType::EVEN_THREAD_COUNT: { return new EvenThreadCount(thread_id, stimulus, correlation); } default: { Utils::error("Invalid selector type: " + to_string((int) instance_type)); - return NULL; // to avoid warnings + return nullptr; // to avoid warnings } } } -pair EvenThreadCount::next() { - pair answer; +pair EvenThreadCount::next() { + pair answer; if (even_thread_id) { answer.first = RequestType::STIMULUS; - answer.second = (void *) stimulus->dequeue(); + answer.second = (void*) stimulus->dequeue(); } else { answer.first = RequestType::CORRELATION; - answer.second = (void *) correlation->dequeue(); + answer.second = (void*) correlation->dequeue(); } return answer; } diff --git a/src/attention_broker/RequestSelector.h b/src/attention_broker/RequestSelector.h index 85aaa36..0c2e8dc 100644 --- a/src/attention_broker/RequestSelector.h +++ b/src/attention_broker/RequestSelector.h @@ -8,31 +8,26 @@ namespace attention_broker_server { using namespace std; using namespace commons; -enum class SelectorType { - EVEN_THREAD_COUNT -}; +enum class SelectorType { EVEN_THREAD_COUNT }; -enum class RequestType { - STIMULUS, - CORRELATION -}; +enum class RequestType { STIMULUS, CORRELATION }; /** - * Abstract class used in WorkerThreads to select the next request to be processed among - * the available request queues. + * Abstract class used in WorkerThreads to select the next request to be + * processed among the available request queues. * - * Concrete subclasses may implement different selection algorithms based in different criteria. + * Concrete subclasses may implement different selection algorithms based in + * different criteria. */ class RequestSelector { - -public: - - virtual ~RequestSelector(); /// Destructor. + public: + virtual ~RequestSelector(); /// Destructor. /** * Factory method. * - * Factory method to instantiate concrete subclasses according to the passed parameter. + * Factory method to instantiate concrete subclasses according to the passed + * parameter. * * @param instance_type Type of concrete subclass to be instantiated. * @param thread_id ID of the thread asking for a new request. @@ -41,53 +36,53 @@ class RequestSelector { * * @return An object of the passed type. */ - static RequestSelector *factory( - SelectorType instance_type, - unsigned int thread_id, - SharedQueue *stimulus, - SharedQueue *correlation); + static RequestSelector* factory(SelectorType instance_type, + unsigned int thread_id, + SharedQueue* stimulus, + SharedQueue* correlation); /** * Return the next request to be processed by the caller worker thread. * * @return the next request to be processed by the caller worker thread. */ - virtual pair next() = 0; + virtual pair next() = 0; -protected: - - RequestSelector(unsigned int thread_id, SharedQueue *stimulus, SharedQueue *correlation); /// Basic constructor. + protected: + RequestSelector(unsigned int thread_id, + SharedQueue* stimulus, + SharedQueue* correlation); /// Basic constructor. unsigned int thread_id; - SharedQueue *stimulus; - SharedQueue *correlation; + SharedQueue* stimulus; + SharedQueue* correlation; }; /** - * Concrete implementation of RequestSelector which evenly distribute worker threads among each type of request. + * Concrete implementation of RequestSelector which evenly distribute worker + * threads among each type of request. * - * This selector keeps half of the working threads working only in "correlate" requests and the other - * half working only in "stimulate" requests. + * This selector keeps half of the working threads working only in "correlate" + * requests and the other half working only in "stimulate" requests. */ class EvenThreadCount : public RequestSelector { - -public: - - ~EvenThreadCount(); /// Destructor. - EvenThreadCount(unsigned int thread_id, SharedQueue *stimulus, SharedQueue *correlation); /// Basic constructor. + public: + ~EvenThreadCount(); /// Destructor. + EvenThreadCount(unsigned int thread_id, + SharedQueue* stimulus, + SharedQueue* correlation); /// Basic constructor. /** * Return the next request to be processed by the caller worker thread. * * @return the next request to be processed by the caller worker thread. */ - pair next(); - -private: + pair next(); + private: bool even_thread_id; }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_REQUESTSELECTOR_H +#endif // _ATTENTION_BROKER_SERVER_REQUESTSELECTOR_H diff --git a/src/attention_broker/StimulusSpreader.cc b/src/attention_broker/StimulusSpreader.cc index d269bc8..b503d70 100644 --- a/src/attention_broker/StimulusSpreader.cc +++ b/src/attention_broker/StimulusSpreader.cc @@ -1,96 +1,90 @@ -#include "expression_hasher.h" #include "StimulusSpreader.h" -#include "HebbianNetwork.h" + +#include +#include + #include "AttentionBrokerServer.h" +#include "HebbianNetwork.h" #include "Utils.h" -#include -#include +#include "expression_hasher.h" using namespace attention_broker_server; // -------------------------------------------------------------------------------- // Public constructors and destructors -StimulusSpreader::~StimulusSpreader() { -} +StimulusSpreader::~StimulusSpreader() = default; -StimulusSpreader::StimulusSpreader() { -} +StimulusSpreader::StimulusSpreader() = default; -StimulusSpreader *StimulusSpreader::factory(StimulusSpreaderType instance_type) { +StimulusSpreader* StimulusSpreader::factory(StimulusSpreaderType instance_type) { switch (instance_type) { - case StimulusSpreaderType::TOKEN : { + case StimulusSpreaderType::TOKEN: { return new TokenSpreader(); } default: { Utils::error("Invalid StimulusSpreaderType: " + to_string((int) instance_type)); - return NULL; // to avoid warnings + return nullptr; // to avoid warnings } } - } -TokenSpreader:: TokenSpreader() { -} +TokenSpreader::TokenSpreader() = default; -TokenSpreader:: ~TokenSpreader() { -} +TokenSpreader::~TokenSpreader() = default; // ------------------------------------------------ // "visit" functions used to traverse network -typedef TokenSpreader::StimuliData DATA; +using DATA = TokenSpreader::StimuliData; -static bool collect_rent(HandleTrie::TrieNode *node, void *data) { - ImportanceType rent = ((DATA *) data)->rent_rate * \ - ((HebbianNetwork::Node *) node->value)->importance; - ((DATA *) data)->total_rent += rent; - ImportanceType wages = 0.0; - ((DATA *) data)->importance_changes->insert( - node->suffix, - new TokenSpreader::ImportanceChanges(rent, wages)); +static bool collect_rent(HandleTrie::TrieNode* node, void* data) { + ImportanceType const rent = + ((DATA*) data)->rent_rate * (dynamic_cast(node->value))->importance; + ((DATA*) data)->total_rent += rent; + ImportanceType const wages = 0.0; + ((DATA*) data) + ->importance_changes->insert(node->suffix, new TokenSpreader::ImportanceChanges(rent, wages)); return false; } -static bool consolidate_rent_and_wages(HandleTrie::TrieNode *node, void *data) { - - HebbianNetwork::Node *value = (HebbianNetwork::Node *) node->value; +static bool consolidate_rent_and_wages(HandleTrie::TrieNode* node, void* data) { + auto* value = dynamic_cast(node->value); - TokenSpreader::ImportanceChanges *changes =\ - (TokenSpreader::ImportanceChanges *) ((DATA *) data)->importance_changes->lookup(node->suffix); + auto* changes = dynamic_cast( + ((DATA*) data)->importance_changes->lookup(node->suffix)); value->importance -= changes->rent; value->importance += changes->wages; // Compute amount to be spread - ImportanceType arity_ratio = (double) value->arity / ((DATA *) data)->largest_arity; - ImportanceType spreading_rate = ((DATA *) data)->spreading_rate_lowerbound + \ - (((DATA *) data)->spreading_rate_range_size * \ - arity_ratio); - ImportanceType to_spread = value->importance * spreading_rate; + ImportanceType const arity_ratio = (double) value->arity / ((DATA*) data)->largest_arity; + ImportanceType const spreading_rate = ((DATA*) data)->spreading_rate_lowerbound + + (((DATA*) data)->spreading_rate_range_size * arity_ratio); + ImportanceType const to_spread = value->importance * spreading_rate; value->importance -= to_spread; value->stimuli_to_spread = to_spread; return false; } -static bool sum_weights(HandleTrie::TrieNode *node, void *data) { - HebbianNetwork::Edge *edge = (HebbianNetwork::Edge *) node->value; - double w = (double) edge->count / edge->node1->count; - ((DATA *) data)->sum_weights += w; +static bool sum_weights(HandleTrie::TrieNode* node, void* data) { + auto* edge = dynamic_cast(node->value); + double const w = (double) edge->count / edge->node1->count; + ((DATA*) data)->sum_weights += w; return false; } -static bool deliver_stimulus(HandleTrie::TrieNode *node, void *data) { - HebbianNetwork::Edge *edge = (HebbianNetwork::Edge *) node->value; - double w = (double) edge->count / edge->node1->count; - ImportanceType stimulus = (w / ((DATA *) data)->sum_weights) * ((DATA *) data)->to_spread; +static bool deliver_stimulus(HandleTrie::TrieNode* node, void* data) { + auto* edge = dynamic_cast(node->value); + double const w = (double) edge->count / edge->node1->count; + ImportanceType const stimulus = (w / ((DATA*) data)->sum_weights) * ((DATA*) data)->to_spread; edge->node2->importance += stimulus; return false; } -static bool consolidate_stimulus(HandleTrie::TrieNode *node, void *data) { - HebbianNetwork::Node *value = (HebbianNetwork::Node *) node->value; - ((DATA *) data)->to_spread = value->stimuli_to_spread; - ((DATA *) data)->sum_weights = 0.0; +static bool consolidate_stimulus(HandleTrie::TrieNode* node, void* data) { + auto* value = dynamic_cast(node->value); + ((DATA*) data)->to_spread = value->stimuli_to_spread; + ((DATA*) data)->sum_weights = 0.0; value->neighbors->traverse(true, &sum_weights, data); value->neighbors->traverse(true, &deliver_stimulus, data); value->stimuli_to_spread = 0.0; @@ -100,28 +94,26 @@ static bool consolidate_stimulus(HandleTrie::TrieNode *node, void *data) { // ------------------------------------------------ // Public methods -void TokenSpreader::distribute_wages( - const dasproto::HandleCount *handle_count, - ImportanceType &total_to_spread, - DATA *data) { - +void TokenSpreader::distribute_wages(const dasproto::HandleCount* handle_count, + ImportanceType& total_to_spread, + DATA* data) { auto iterator = handle_count->map().find("SUM"); if (iterator == handle_count->map().end()) { Utils::error("Missing 'SUM' key in HandleCount request"); } - unsigned int total_wages = iterator->second; - for (auto pair: handle_count->map()) { + unsigned int const total_wages = iterator->second; + for (const auto& pair : handle_count->map()) { if (pair.first != "SUM") { - double normalized_amount = (((double) pair.second) * total_to_spread) / total_wages; - data->importance_changes->insert(pair.first, new TokenSpreader::ImportanceChanges(0.0, normalized_amount)); + double const normalized_amount = (((double) pair.second) * total_to_spread) / total_wages; + data->importance_changes->insert( + pair.first, new TokenSpreader::ImportanceChanges(0.0, normalized_amount)); } } } -void TokenSpreader::spread_stimuli(const dasproto::HandleCount *request) { - - HebbianNetwork *network = (HebbianNetwork *) request->hebbian_network(); - if (network == NULL) { +void TokenSpreader::spread_stimuli(const dasproto::HandleCount* request) { + auto* network = (HebbianNetwork*) request->hebbian_network(); + if (network == nullptr) { return; } @@ -129,13 +121,13 @@ void TokenSpreader::spread_stimuli(const dasproto::HandleCount *request) { data.importance_changes = new HandleTrie(HANDLE_HASH_SIZE - 1); data.rent_rate = AttentionBrokerServer::RENT_RATE; data.spreading_rate_lowerbound = AttentionBrokerServer::SPREADING_RATE_LOWERBOUND; - data.spreading_rate_range_size = \ - AttentionBrokerServer::SPREADING_RATE_UPPERBOUND - AttentionBrokerServer::SPREADING_RATE_LOWERBOUND; + data.spreading_rate_range_size = AttentionBrokerServer::SPREADING_RATE_UPPERBOUND - + AttentionBrokerServer::SPREADING_RATE_LOWERBOUND; data.largest_arity = network->largest_arity; data.total_rent = 0.0; // Collect rent - network->visit_nodes(true, &collect_rent, (void *) &data); + network->visit_nodes(true, &collect_rent, (void*) &data); // Distribute wages ImportanceType total_to_spread = network->alienate_tokens(); @@ -143,7 +135,7 @@ void TokenSpreader::spread_stimuli(const dasproto::HandleCount *request) { distribute_wages(request, total_to_spread, &data); // Consolidate changes - network->visit_nodes(true, &consolidate_rent_and_wages, (void *) &data); + network->visit_nodes(true, &consolidate_rent_and_wages, (void*) &data); // Spread activation (1 cycle) network->visit_nodes(true, &consolidate_stimulus, &data); diff --git a/src/attention_broker/StimulusSpreader.h b/src/attention_broker/StimulusSpreader.h index 5a9ae2e..be413a3 100644 --- a/src/attention_broker/StimulusSpreader.h +++ b/src/attention_broker/StimulusSpreader.h @@ -1,9 +1,9 @@ #ifndef _ATTENTION_BROKER_SERVER_STIMULUSSPREADER_H #define _ATTENTION_BROKER_SERVER_STIMULUSSPREADER_H -#include "attention_broker.grpc.pb.h" -#include "Utils.h" #include "HebbianNetwork.h" +#include "Utils.h" +#include "attention_broker.grpc.pb.h" using namespace std; @@ -13,86 +13,88 @@ namespace attention_broker_server { * Algorithm used to update HebbianNetwork weights in "stimulate" requests. */ enum class StimulusSpreaderType { - TOKEN /// Consider importance as a fixed amount of tokens distributed among atoms in the HebbianNetwork. + TOKEN /// Consider importance as a fixed amount of tokens distributed among + /// atoms in the HebbianNetwork. }; /** - * Process stimuli spreading requests by boosting importance of the atoms passed in the request - * and running one cycle of stimuli spreading in the Hebbian Network. + * Process stimuli spreading requests by boosting importance of the atoms passed + * in the request and running one cycle of stimuli spreading in the Hebbian + * Network. + * + * Objects of this class are used by worker threads to process "stimulate" + * requests. * - * Objects of this class are used by worker threads to process "stimulate" requests. + * The request have a list of pairs (handle, n) with the handles whose + * importance should be boosted and the relative magnitude of this boost + * (compared to the other handles in the same request). * - * The request have a list of pairs (handle, n) with the handles whose importance should be - * boosted and the relative magnitude of this boost (compared to the other handles in the same - * request). + * This is an abstract class. Concrete subclasses implement different ways of + * spreading stimuli in the HebbianNetwork. * - * This is an abstract class. Concrete subclasses implement different ways of spreading stimuli - * in the HebbianNetwork. - * */ class StimulusSpreader { - -public: - + public: /** * Factory method. * - * Factory method to instantiate concrete subclasses according to the passed parameter. + * Factory method to instantiate concrete subclasses according to the passed + * parameter. * * @param instance_type Type of concrete subclass to be instantiated. * * @return An object of the passed type. */ - static StimulusSpreader *factory(StimulusSpreaderType instance_type); - virtual ~StimulusSpreader(); /// destructor. + static StimulusSpreader* factory(StimulusSpreaderType instance_type); + virtual ~StimulusSpreader(); /// destructor. /** * Stimulate atoms and run one cycle of stimuli spreading. * - * Atoms in the passed list have their importance boosted according to the passed counts. Then - * one cycle of stimuli spreading is executed. + * Atoms in the passed list have their importance boosted according to the + * passed counts. Then one cycle of stimuli spreading is executed. * - * @param request A list of handles to be boosted and respective counts which are used to determine - * the magnitude of such boost. The actual way importance is boosted and then spread among HebbianNetwork - * links are delegated to the concrete subclasses. + * @param request A list of handles to be boosted and respective counts which + * are used to determine the magnitude of such boost. The actual way + * importance is boosted and then spread among HebbianNetwork links are + * delegated to the concrete subclasses. */ - virtual void spread_stimuli(const dasproto::HandleCount *request) = 0; - -protected: - - StimulusSpreader(); /// Basic empty constructor. + virtual void spread_stimuli(const dasproto::HandleCount* request) = 0; -private: + protected: + StimulusSpreader(); /// Basic empty constructor. + private: }; /** - * Process stimuli spreading requests by boosting importance of the atoms passed in the request - * and running one cycle of stimuli spreading in the Hebbian Network. + * Process stimuli spreading requests by boosting importance of the atoms passed + * in the request and running one cycle of stimuli spreading in the Hebbian + * Network. * - * Objects of this class are used by worker threads to process "stimulate" requests. + * Objects of this class are used by worker threads to process "stimulate" + * requests. * - * The request have a list of pairs (handle, n) with the handles whose importance should be - * boosted and the relative magnitude of this boost (compared to the other handles in the same - * request). + * The request have a list of pairs (handle, n) with the handles whose + * importance should be boosted and the relative magnitude of this boost + * (compared to the other handles in the same request). * - * This StimulusSpreader consider a fixed amount of tokens distributed among all atoms in the - * HebbianNetwork. Importance boosts and stimulus spreading are implemented in a way that this - * total amount of tokens remains fixed, unless explicitly requested by caller. + * This StimulusSpreader consider a fixed amount of tokens distributed among all + * atoms in the HebbianNetwork. Importance boosts and stimulus spreading are + * implemented in a way that this total amount of tokens remains fixed, unless + * explicitly requested by caller. */ -class TokenSpreader: public StimulusSpreader { - -public: - - TokenSpreader(); /// Basic empty constructor. - ~TokenSpreader(); /// Destructor. +class TokenSpreader : public StimulusSpreader { + public: + TokenSpreader(); /// Basic empty constructor. + ~TokenSpreader(); /// Destructor. // data structure used as parameter container in "visit" functions // used in trie traversal typedef struct { ImportanceType rent_rate; ImportanceType total_rent; - HandleTrie *importance_changes; + HandleTrie* importance_changes; unsigned int largest_arity; ImportanceType spreading_rate_lowerbound; ImportanceType spreading_rate_range_size; @@ -101,43 +103,45 @@ class TokenSpreader: public StimulusSpreader { } StimuliData; // data structure used in a private trie during importance update calculations - class ImportanceChanges: public HandleTrie::TrieValue { - public: - ImportanceType rent; - ImportanceType wages; - ImportanceChanges(ImportanceType r, ImportanceType w) { - rent = r; - wages = w; - } - void merge(TrieValue *other) { - rent += ((ImportanceChanges *) other)->rent; - wages += ((ImportanceChanges *) other)->wages; - } + class ImportanceChanges : public HandleTrie::TrieValue { + public: + ImportanceType rent; + ImportanceType wages; + ImportanceChanges(ImportanceType r, ImportanceType w) { + rent = r; + wages = w; + } + void merge(TrieValue* other) { + rent += ((ImportanceChanges*) other)->rent; + wages += ((ImportanceChanges*) other)->wages; + } }; /** * Stimulate atoms and run one cycle of stimuli spreading. * - * Atoms in the passed list have their importance boosted according to the passed counts. Then - * one cycle of stimuli spreading is executed. + * Atoms in the passed list have their importance boosted according to the + * passed counts. Then one cycle of stimuli spreading is executed. * - * Boosts and stimuli spreading are actually tokens which are collected from all the nodes in the - * HebbianNetwork (as a rent) and redistributed according to the passed * counts (as wages). Once - * rents and wages are consolidated in each node's importance, one cycle of stimuli spreading is run - * when a % of the importance tokens of each node being redistributed to amnongst its neighbors - * according to the weights of the links in the HebbianNetwork. + * Boosts and stimuli spreading are actually tokens which are collected from + * all the nodes in the HebbianNetwork (as a rent) and redistributed according + * to the passed * counts (as wages). Once rents and wages are consolidated in + * each node's importance, one cycle of stimuli spreading is run when a % of + * the importance tokens of each node being redistributed to amnongst its + * neighbors according to the weights of the links in the HebbianNetwork. * - * @param request A list of handles to be boosted and respective counts which are used to determine - * the magnitude of such boost. + * @param request A list of handles to be boosted and respective counts which + * are used to determine the magnitude of such boost. */ - void spread_stimuli(const dasproto::HandleCount *request); - - // Used only in "visit" functions during trie traversals. Such functions aren't methods so this method - // must be public. - void distribute_wages(const dasproto::HandleCount *handle_count, ImportanceType &total_to_spread, StimuliData *data); + void spread_stimuli(const dasproto::HandleCount* request); + // Used only in "visit" functions during trie traversals. Such functions + // aren't methods so this method must be public. + void distribute_wages(const dasproto::HandleCount* handle_count, + ImportanceType& total_to_spread, + StimuliData* data); }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_STIMULUSSPREADER_H +#endif // _ATTENTION_BROKER_SERVER_STIMULUSSPREADER_H diff --git a/src/attention_broker/WorkerThreads.cc b/src/attention_broker/WorkerThreads.cc index 90020eb..cc06641 100644 --- a/src/attention_broker/WorkerThreads.cc +++ b/src/attention_broker/WorkerThreads.cc @@ -1,12 +1,13 @@ +#include "WorkerThreads.h" + #include #include "AttentionBrokerServer.h" -#include "attention_broker.grpc.pb.h" -#include "Utils.h" -#include "RequestSelector.h" -#include "WorkerThreads.h" #include "HebbianNetworkUpdater.h" +#include "RequestSelector.h" #include "StimulusSpreader.h" +#include "Utils.h" +#include "attention_broker.grpc.pb.h" using namespace attention_broker_server; using namespace std; @@ -14,59 +15,50 @@ using namespace std; // -------------------------------------------------------------------------------- // Public methods -WorkerThreads::WorkerThreads(SharedQueue *stimulus, SharedQueue *correlation) { - stimulus_requests = stimulus; - correlation_requests = correlation; - threads_count = AttentionBrokerServer::WORKER_THREADS_COUNT; +WorkerThreads::WorkerThreads(SharedQueue* stimulus, SharedQueue* correlation) + : stimulus_requests(stimulus), + correlation_requests(correlation), + threads_count(AttentionBrokerServer::WORKER_THREADS_COUNT) { for (unsigned int i = 0; i < threads_count; i++) { - threads.push_back(new thread( - &WorkerThreads::worker_thread, - this, - i, - stimulus_requests, - correlation_requests)); + threads.push_back( + new thread(&WorkerThreads::worker_thread, this, i, stimulus_requests, correlation_requests)); } } -WorkerThreads::~WorkerThreads() { -} +WorkerThreads::~WorkerThreads() = default; void WorkerThreads::graceful_stop() { stop_flag_mutex.lock(); stop_flag = true; stop_flag_mutex.unlock(); - for (thread *worker_thread: threads) { + for (thread* worker_thread : threads) { worker_thread->join(); } } - + // -------------------------------------------------------------------------------- // Private methods -void WorkerThreads::worker_thread( - unsigned int thread_id, - SharedQueue *stimulus_requests, - SharedQueue *correlation_requests) { - - RequestSelector *selector = RequestSelector::factory( - SelectorType::EVEN_THREAD_COUNT, - thread_id, - stimulus_requests, - correlation_requests); - HebbianNetworkUpdater *updater = HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); - StimulusSpreader *stimulus_spreader = StimulusSpreader::factory(StimulusSpreaderType::TOKEN); - pair request; +void WorkerThreads::worker_thread(unsigned int thread_id, + SharedQueue* stimulus_requests, + SharedQueue* correlation_requests) { + RequestSelector* selector = RequestSelector::factory( + SelectorType::EVEN_THREAD_COUNT, thread_id, stimulus_requests, correlation_requests); + HebbianNetworkUpdater* updater = + HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); + StimulusSpreader* stimulus_spreader = StimulusSpreader::factory(StimulusSpreaderType::TOKEN); + pair request; bool stop = false; - while (! stop) { + while (!stop) { request = selector->next(); if (request.second != NULL) { switch (request.first) { case RequestType::STIMULUS: { - stimulus_spreader->spread_stimuli((dasproto::HandleCount *) request.second); + stimulus_spreader->spread_stimuli((dasproto::HandleCount*) request.second); break; } case RequestType::CORRELATION: { - updater->correlation((dasproto::HandleList *) request.second); + updater->correlation((dasproto::HandleList*) request.second); break; } default: { diff --git a/src/attention_broker/WorkerThreads.h b/src/attention_broker/WorkerThreads.h index 38c429f..c1869ae 100644 --- a/src/attention_broker/WorkerThreads.h +++ b/src/attention_broker/WorkerThreads.h @@ -1,11 +1,11 @@ #ifndef _ATTENTION_BROKER_SERVER_WORKERTHREADS_H #define _ATTENTION_BROKER_SERVER_WORKERTHREADS_H -#include #include +#include +#include #include #include -#include #include "SharedQueue.h" @@ -17,50 +17,49 @@ namespace attention_broker_server { /** * Used in AttentionBrokerServer to keep track of worker threads. * - * WorkerThreads provides an abstraction to actual threads creation and shutdown. + * WorkerThreads provides an abstraction to actual threads creation and + * shutdown. */ class WorkerThreads { - -public: - + public: /** * Constructor. * - * Start n worker threads (n is a parameter defined in AttentionBrokerServer) and - * keep then running getting requests from the queues which have been passed as - * parameters. + * Start n worker threads (n is a parameter defined in AttentionBrokerServer) + * and keep then running getting requests from the queues which have been + * passed as parameters. * - * Working threads can process any type of requests. The policy of which request - * queue a worker thread will read from next is determined by RequestSelector. + * Working threads can process any type of requests. The policy of which + * request queue a worker thread will read from next is determined by + * RequestSelector. */ - WorkerThreads(SharedQueue *stimulus, SharedQueue *correlation); - ~WorkerThreads(); /// Destructor. + WorkerThreads(SharedQueue* stimulus, SharedQueue* correlation); + ~WorkerThreads(); /// Destructor. /** * Gracefully and synchronously stop all threads. * - * Sets a flag which is check by each thread when the requests queue are empty. It means - * that both requests queues will be processed before the threads actually stop. When - * both requests queues are empty, threads return and are destroyed. This method will wait - * for all threads to finish before returning. + * Sets a flag which is check by each thread when the requests queue are + * empty. It means that both requests queues will be processed before the + * threads actually stop. When both requests queues are empty, threads return + * and are destroyed. This method will wait for all threads to finish before + * returning. */ void graceful_stop(); -private: - + private: unsigned int threads_count; - vector threads; + vector threads; bool stop_flag = false; - SharedQueue *stimulus_requests; - SharedQueue *correlation_requests; + SharedQueue* stimulus_requests; + SharedQueue* correlation_requests; mutex stop_flag_mutex; - void worker_thread( - unsigned int thread_id, - SharedQueue *stimulus_requests, - SharedQueue *correlation_requests); + void worker_thread(unsigned int thread_id, + SharedQueue* stimulus_requests, + SharedQueue* correlation_requests); }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_WORKERTHREADS_H +#endif // _ATTENTION_BROKER_SERVER_WORKERTHREADS_H diff --git a/src/commons/SharedQueue.cc b/src/commons/SharedQueue.cc index bea0575..f26154f 100644 --- a/src/commons/SharedQueue.cc +++ b/src/commons/SharedQueue.cc @@ -13,9 +13,7 @@ SharedQueue::SharedQueue(unsigned int initial_size) { end = 0; } -SharedQueue::~SharedQueue() { - delete [] requests; -} +SharedQueue::~SharedQueue() { delete[] requests; } bool SharedQueue::empty() { bool answer; @@ -25,7 +23,7 @@ bool SharedQueue::empty() { return answer; } -void SharedQueue::enqueue(void *request) { +void SharedQueue::enqueue(void* request) { shared_queue_mutex.lock(); if (count == size) { enlarge_shared_queue(); @@ -36,8 +34,8 @@ void SharedQueue::enqueue(void *request) { shared_queue_mutex.unlock(); } -void *SharedQueue::dequeue() { - void *answer = NULL; +void* SharedQueue::dequeue() { + void* answer = NULL; shared_queue_mutex.lock(); if (count > 0) { answer = requests[start]; @@ -51,28 +49,20 @@ void *SharedQueue::dequeue() { // -------------------------------------------------------------------------------- // Protected methods -unsigned int SharedQueue::current_size() { - return size; -} +unsigned int SharedQueue::current_size() { return size; } -unsigned int SharedQueue::current_start() { - return start; -} +unsigned int SharedQueue::current_start() { return start; } -unsigned int SharedQueue::current_end() { - return end; -} +unsigned int SharedQueue::current_end() { return end; } -unsigned int SharedQueue::current_count() { - return count; -} +unsigned int SharedQueue::current_count() { return count; } // -------------------------------------------------------------------------------- // Private methods void SharedQueue::enlarge_shared_queue() { unsigned int _new_size = size * 2; - void **_new_queue = new void*[_new_size]; + void** _new_queue = new void*[_new_size]; unsigned int _cursor = start; unsigned int _new_cursor = 0; do { @@ -82,7 +72,7 @@ void SharedQueue::enlarge_shared_queue() { size = _new_size; start = 0; end = _new_cursor; - delete [] requests; + delete[] requests; requests = _new_queue; // count remains unchanged } diff --git a/src/commons/SharedQueue.h b/src/commons/SharedQueue.h index 41b0b03..07a74dc 100644 --- a/src/commons/SharedQueue.h +++ b/src/commons/SharedQueue.h @@ -6,52 +6,51 @@ namespace commons { /** - * Data abstraction of a synchronized (thread-safe) queue for assynchronous requests. + * Data abstraction of a synchronized (thread-safe) queue for assynchronous + * requests. * - * Internally, this abstraction uses an array of requests to avoid the need to create cell - * objects on every insertion. Because of this, on new insertions it's possible to reach queue - * size limit during an insertion. When that happens, the array is doubled in size. Initial size - * is passed as a constructor's parameter. + * Internally, this abstraction uses an array of requests to avoid the need to + * create cell objects on every insertion. Because of this, on new insertions + * it's possible to reach queue size limit during an insertion. When that + * happens, the array is doubled in size. Initial size is passed as a + * constructor's parameter. */ class SharedQueue { + public: + SharedQueue(unsigned int initial_size = 1000); // Basic constructor -public: - - SharedQueue(unsigned int initial_size = 1000); // Basic constructor - - ~SharedQueue(); /// Destructor. + ~SharedQueue(); /// Destructor. /** * Enqueues a request. * * @param request Request to be queued. */ - void enqueue(void *request); + void enqueue(void* request); /** * Dequeues a request. * * @return The dequeued request. */ - void *dequeue(); + void* dequeue(); /** * Returns true iff the queue is empty. */ bool empty(); -protected: - + protected: unsigned int current_size(); unsigned int current_start(); unsigned int current_end(); unsigned int current_count(); -private: - + private: std::mutex shared_queue_mutex; - void **requests; // GRPC documentation states that request types should not be inherited + void** requests; // GRPC documentation states that request types should not be + // inherited unsigned int size; unsigned int count; unsigned int start; @@ -60,6 +59,6 @@ class SharedQueue { void enlarge_shared_queue(); }; -} // namespace commons +} // namespace commons -#endif // _COMMONS_SHAREDQUEUE_H +#endif // _COMMONS_SHAREDQUEUE_H diff --git a/src/commons/Utils.cc b/src/commons/Utils.cc index 2210002..3915360 100644 --- a/src/commons/Utils.cc +++ b/src/commons/Utils.cc @@ -1,31 +1,25 @@ -#include +#include "Utils.h" + #include -#include -#include +#include #include +#include #include +#include #include -#include "Utils.h" - using namespace commons; using namespace std; // -------------------------------------------------------------------------------- // Public methods -Utils::Utils() { -} +Utils::Utils() {} -Utils::~Utils() { -} +Utils::~Utils() {} -void Utils::error(string msg) { - throw runtime_error(msg); -} -void Utils::warning(string msg) { - cerr << msg << endl; -} +void Utils::error(string msg) { throw runtime_error(msg); } +void Utils::warning(string msg) { cerr << msg << endl; } bool Utils::flip_coin(double true_probability) { long f = 1000; @@ -36,18 +30,15 @@ void Utils::sleep(unsigned int milliseconds) { this_thread::sleep_for(chrono::milliseconds(milliseconds)); } -string Utils::get_environment(string const &key) { - char *value = getenv(key.c_str()); +string Utils::get_environment(string const& key) { + char* value = getenv(key.c_str()); string answer = (value == NULL ? "" : value); return answer; } -StopWatch::StopWatch() { - reset(); -} +StopWatch::StopWatch() { reset(); } -StopWatch::~StopWatch() { -} +StopWatch::~StopWatch() {} void StopWatch::start() { if (running) { @@ -76,7 +67,6 @@ unsigned long StopWatch::milliseconds() { } string StopWatch::str_time() { - unsigned long millis = milliseconds(); unsigned long seconds = millis / 1000; @@ -93,10 +83,10 @@ string StopWatch::str_time() { } else if (minutes > 0) { return to_string(minutes) + " mins " + to_string(seconds) + " secs"; } else if (seconds > 0) { - //double s = ((double) ((seconds * 1000) + millis)) / 1000.0; - //std::stringstream stream; - //stream << std::fixed << std::setprecision(3) << s; - //return stream.str() + " secs"; + // double s = ((double) ((seconds * 1000) + millis)) / 1000.0; + // std::stringstream stream; + // stream << std::fixed << std::setprecision(3) << s; + // return stream.str() + " secs"; return to_string(seconds) + " secs " + to_string(millis) + " millis"; } else { return to_string(millis) + " millis"; diff --git a/src/commons/Utils.h b/src/commons/Utils.h index 4230dbc..1f4a142 100644 --- a/src/commons/Utils.h +++ b/src/commons/Utils.h @@ -1,32 +1,31 @@ #ifndef _COMMONS_UTILS_H #define _COMMONS_UTILS_H -#include #include +#include using namespace std; namespace commons { class StopWatch { - public: - StopWatch(); - ~StopWatch(); - void start(); - void stop(); - void reset(); - unsigned long milliseconds(); - string str_time(); - private: - bool running; - chrono::steady_clock::time_point start_time; - chrono::steady_clock::duration accumulator; + public: + StopWatch(); + ~StopWatch(); + void start(); + void stop(); + void reset(); + unsigned long milliseconds(); + string str_time(); + + private: + bool running; + chrono::steady_clock::time_point start_time; + chrono::steady_clock::duration accumulator; }; class Utils { - -public: - + public: Utils(); ~Utils(); @@ -34,9 +33,9 @@ class Utils { static void warning(string msg); static bool flip_coin(double true_probability = 0.5); static void sleep(unsigned int milliseconds = 100); - static string get_environment(string const &key); + static string get_environment(string const& key); }; -} // namespace commons +} // namespace commons -#endif // _COMMONS_UTILS_H +#endif // _COMMONS_UTILS_H diff --git a/src/distributed_algorithm_node/DistributedAlgorithmNode.cc b/src/distributed_algorithm_node/DistributedAlgorithmNode.cc index dcd576f..0500e26 100644 --- a/src/distributed_algorithm_node/DistributedAlgorithmNode.cc +++ b/src/distributed_algorithm_node/DistributedAlgorithmNode.cc @@ -1,26 +1,23 @@ #include "DistributedAlgorithmNode.h" + #include "Utils.h" using namespace distributed_algorithm_node; using namespace commons; -DistributedAlgorithmNode::DistributedAlgorithmNode( - const string &node_id, - LeadershipBrokerType leadership_algorithm, - MessageBrokerType messaging_backend) { - +DistributedAlgorithmNode::DistributedAlgorithmNode(const string& node_id, + LeadershipBrokerType leadership_algorithm, + MessageBrokerType messaging_backend) { this->my_node_id = node_id; this->leadership_broker = LeadershipBroker::factory(leadership_algorithm); - this->message_broker = MessageBroker::factory( - messaging_backend, - // Empty destructor to avoid node deletion - shared_ptr(this, [](MessageFactory *) {}), - node_id); + this->message_broker = + MessageBroker::factory(messaging_backend, + // Empty destructor to avoid node deletion + shared_ptr(this, [](MessageFactory*) {}), + node_id); } -DistributedAlgorithmNode::~DistributedAlgorithmNode() { - this->graceful_shutdown(); -} +DistributedAlgorithmNode::~DistributedAlgorithmNode() { this->graceful_shutdown(); } // ------------------------------------------------------------------------------------------------- // Public API @@ -28,10 +25,10 @@ DistributedAlgorithmNode::~DistributedAlgorithmNode() { void DistributedAlgorithmNode::join_network() { this->leadership_broker->set_message_broker(this->message_broker); this->message_broker->join_network(); - //Utils::sleep(1000); + // Utils::sleep(1000); string my_leadership_vote = this->cast_leadership_vote(); this->leadership_broker->start_leader_election(my_leadership_vote); - while (! this->has_leader()) { + while (!this->has_leader()) { Utils::sleep(); } vector args; @@ -39,39 +36,30 @@ void DistributedAlgorithmNode::join_network() { this->message_broker->broadcast(this->known_commands.NODE_JOINED_NETWORK, args); } -bool DistributedAlgorithmNode::is_leader() { - return (this->leader_id() == this->node_id()); -} +bool DistributedAlgorithmNode::is_leader() { return (this->leader_id() == this->node_id()); } -string DistributedAlgorithmNode::leader_id() { - return this->leadership_broker->leader_id(); -} +string DistributedAlgorithmNode::leader_id() { return this->leadership_broker->leader_id(); } -bool DistributedAlgorithmNode::has_leader() { - return this->leadership_broker->has_leader(); -} +bool DistributedAlgorithmNode::has_leader() { return this->leadership_broker->has_leader(); } -void DistributedAlgorithmNode::add_peer(const string &peer_id) { +void DistributedAlgorithmNode::add_peer(const string& peer_id) { this->message_broker->add_peer(peer_id); } -string DistributedAlgorithmNode::node_id() { - return this->my_node_id; -} +string DistributedAlgorithmNode::node_id() { return this->my_node_id; } -void DistributedAlgorithmNode::broadcast(const string &command, const vector &args) { +void DistributedAlgorithmNode::broadcast(const string& command, const vector& args) { this->message_broker->broadcast(command, args); } -void DistributedAlgorithmNode::send( - const string &command, - const vector &args, - const string &recipient) { - +void DistributedAlgorithmNode::send(const string& command, + const vector& args, + const string& recipient) { this->message_broker->send(command, args, recipient); } -std::shared_ptr DistributedAlgorithmNode::message_factory(string &command, vector &args) { +std::shared_ptr DistributedAlgorithmNode::message_factory(string& command, + vector& args) { if (command == this->known_commands.NODE_JOINED_NETWORK) { return std::shared_ptr(new NodeJoinedNetwork(args[0])); } else { @@ -79,6 +67,4 @@ std::shared_ptr DistributedAlgorithmNode::message_factory(string &comma } } -void DistributedAlgorithmNode::graceful_shutdown() { - this->message_broker->graceful_shutdown(); -} +void DistributedAlgorithmNode::graceful_shutdown() { this->message_broker->graceful_shutdown(); } diff --git a/src/distributed_algorithm_node/DistributedAlgorithmNode.h b/src/distributed_algorithm_node/DistributedAlgorithmNode.h index 5c0e6d4..893ce90 100644 --- a/src/distributed_algorithm_node/DistributedAlgorithmNode.h +++ b/src/distributed_algorithm_node/DistributedAlgorithmNode.h @@ -1,12 +1,13 @@ #ifndef _DISTRIBUTED_ALGORITHM_NODE_DISTRIBUTEDALGORITHMNODE_H #define _DISTRIBUTED_ALGORITHM_NODE_DISTRIBUTEDALGORITHMNODE_H -#include "LeadershipBroker.h" -#include "MessageBroker.h" -#include "Message.h" #include #include +#include "LeadershipBroker.h" +#include "Message.h" +#include "MessageBroker.h" + using namespace std; namespace distributed_algorithm_node { @@ -14,44 +15,47 @@ namespace distributed_algorithm_node { /** * Implements a node in a network used for some distributed processing. * - * This is an abstract class so users of this module are supposed to extend it to - * implement its own distributed network. + * This is an abstract class so users of this module are supposed to extend it + * to implement its own distributed network. * * Communication between nodes are performed by Message objects which are like * a piece of code sent from one node to another. We don't actually send * code but instead we send a reference to what type of Message object is being - * exchanged so once the message arrive in the recipient a Message object is built - * and its code is executed. The "reference" about what type of Message is being - * exchanged is encoded like command lines with commands and its arguments. + * exchanged so once the message arrive in the recipient a Message object is + * built and its code is executed. The "reference" about what type of Message is + * being exchanged is encoded like command lines with commands and its + * arguments. * * This is what you should care about when extending DistributedAlgorithmNode: * - * - DistributedAlgorithmNode is the class that build Message objects. That's why it extends - * MessageFactory. This abstract class already knows how to build some basic Message - * objects for some commands which are common to all the networks (e.g. joining - * of new nodes to the network) but subclasses of DistributedAlgorithmNode should re-implement - * message_factory() to build Message objects for its own distributed application. - * - Message commands are executed in separated threads. So if such commands updates some - * state variable inside DistributedAlgorithmNode or its subclasses, this state variable should - * be protected by mutual exclusion primitives. - * - DistributedAlgorithmNode's constructor expects allocated objects for MessageBroker and - * LeadershipBroker. These are abstract classes which may have many concrete - * implementations. When designing your distributed network you need to decide - * which messaging system is supposed to be used to actually make the communication - * bwtween nodes. You can use one of the concrete implementations we provide or you - * can provide your own implementation extending these abstract classes. Typically, users - * wouldn't need to implement its own messaging system but it may be the case for the - * leadership election algorithm as this is highly dependent on the network topology - * and expected behaviour. - * - DistributedAlgorithmNode has some pure virtual methods that need to be implemented. These are - * the methods called by basic Message objects to acomplish basic tasks like leadership - * election and notification of new nodes joning the network. The proper way to respond - * to these requests are delegated to concrete classes extending DistributedAlgorithmNode. + * - DistributedAlgorithmNode is the class that build Message objects. That's + * why it extends MessageFactory. This abstract class already knows how to build + * some basic Message objects for some commands which are common to all the + * networks (e.g. joining of new nodes to the network) but subclasses of + * DistributedAlgorithmNode should re-implement message_factory() to build + * Message objects for its own distributed application. + * - Message commands are executed in separated threads. So if such commands + * updates some state variable inside DistributedAlgorithmNode or its + * subclasses, this state variable should be protected by mutual exclusion + * primitives. + * - DistributedAlgorithmNode's constructor expects allocated objects for + * MessageBroker and LeadershipBroker. These are abstract classes which may have + * many concrete implementations. When designing your distributed network you + * need to decide which messaging system is supposed to be used to actually make + * the communication bwtween nodes. You can use one of the concrete + * implementations we provide or you can provide your own implementation + * extending these abstract classes. Typically, users wouldn't need to implement + * its own messaging system but it may be the case for the leadership election + * algorithm as this is highly dependent on the network topology and expected + * behaviour. + * - DistributedAlgorithmNode has some pure virtual methods that need to be + * implemented. These are the methods called by basic Message objects to + * acomplish basic tasks like leadership election and notification of new nodes + * joning the network. The proper way to respond to these requests are delegated + * to concrete classes extending DistributedAlgorithmNode. */ class DistributedAlgorithmNode : public MessageFactory { - -public: - + public: /** * Destructor. */ @@ -60,16 +64,15 @@ class DistributedAlgorithmNode : public MessageFactory { /** * Basic constructor. * - * @param node_id The ID of this node. Typically is a string to identify this node - * in the MessageBroker. - * @param leadership_algorithm The concrete class to be used as leadership broker. + * @param node_id The ID of this node. Typically is a string to identify this + * node in the MessageBroker. + * @param leadership_algorithm The concrete class to be used as leadership + * broker. * @param messaging_backend The concrete class to be used as message broker. */ - DistributedAlgorithmNode( - const string &node_id, - LeadershipBrokerType leadership_algorithm, - MessageBrokerType messaging_backend - ); + DistributedAlgorithmNode(const string& node_id, + LeadershipBrokerType leadership_algorithm, + MessageBrokerType messaging_backend); // -------------------------------------------------------------------------------------------- // Public API @@ -87,9 +90,11 @@ class DistributedAlgorithmNode : public MessageFactory { bool is_leader(); /** - * Returns the id of the network leader, or "" if no leader is known by this node. + * Returns the id of the network leader, or "" if no leader is known by this + * node. * - * @return The id of the network leader, or "" if no leader is known by this node. + * @return The id of the network leader, or "" if no leader is known by this + * node. */ string leader_id(); @@ -103,12 +108,12 @@ class DistributedAlgorithmNode : public MessageFactory { /** * Adds a node in the list of known peers. * - * Note that this methods DOESN'T add the passed peer into the network. The peer is - * supposed to be already in the network. + * Note that this methods DOESN'T add the passed peer into the network. The + * peer is supposed to be already in the network. * * @param peer_id The ID of the node being added as a peer. */ - void add_peer(const string &peer_id); + void add_peer(const string& peer_id); /** * Returns this node's ID. @@ -120,24 +125,25 @@ class DistributedAlgorithmNode : public MessageFactory { /** * Broadcasts a command to all nodes in the network. * - * All nodes in the network will be reached (not only the known peers) and the command - * will be executed. + * All nodes in the network will be reached (not only the known peers) and the + * command will be executed. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. */ - void broadcast(const string &command, const vector &args); + void broadcast(const string& command, const vector& args); /** * Sends a command to the passed node. * - * The target node is supposed to be a known peer. If not, an exception is thrown. + * The target node is supposed to be a known peer. If not, an exception is + * thrown. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. * @recipient The target node for the command. */ - void send(const string &command, const vector &args, const string &recipient); + void send(const string& command, const vector& args, const string& recipient); /** * Build the Message object which is supposed to execute the passed command. @@ -146,7 +152,7 @@ class DistributedAlgorithmNode : public MessageFactory { * @param args Arguments for the command. * @return A Message object */ - virtual shared_ptr message_factory(string &command, vector &args); + virtual shared_ptr message_factory(string& command, vector& args); /** * Gracefully shuts down threads or any other resources being used. @@ -159,23 +165,24 @@ class DistributedAlgorithmNode : public MessageFactory { /** * This method is called whenever a new node joins the network. * - * Every node that joins the network will broadcast a Message to everyone already joined. - * However, it's up to each node to decide whether or not the newly joined node will be added - * as a known peer. + * Every node that joins the network will broadcast a Message to everyone + * already joined. However, it's up to each node to decide whether or not the + * newly joined node will be added as a known peer. * * @param node_id The ID of the newly joined node. */ - virtual void node_joined_network(const string &node_id) = 0; + virtual void node_joined_network(const string& node_id) = 0; /** - * Casts a vote (which is the ID of the node being voted) in a leadership election. + * Casts a vote (which is the ID of the node being voted) in a leadership + * election. * - * @return This node's vote (which is the ID of the node being voted) for leader. + * @return This node's vote (which is the ID of the node being voted) for + * leader. */ virtual string cast_leadership_vote() = 0; -private: - + private: struct { string NODE_JOINED_NETWORK = "node_joined_network"; } known_commands; @@ -185,6 +192,6 @@ class DistributedAlgorithmNode : public MessageFactory { shared_ptr message_broker; }; -} // namespace distributed_algorithm_node +} // namespace distributed_algorithm_node -#endif // _DISTRIBUTED_ALGORITHM_NODE_DISTRIBUTEDALGORITHMNODE_H +#endif // _DISTRIBUTED_ALGORITHM_NODE_DISTRIBUTEDALGORITHMNODE_H diff --git a/src/distributed_algorithm_node/LeadershipBroker.cc b/src/distributed_algorithm_node/LeadershipBroker.cc index ec48b27..e0a1783 100644 --- a/src/distributed_algorithm_node/LeadershipBroker.cc +++ b/src/distributed_algorithm_node/LeadershipBroker.cc @@ -1,4 +1,5 @@ #include "LeadershipBroker.h" + #include "Utils.h" using namespace distributed_algorithm_node; @@ -6,16 +7,13 @@ using namespace distributed_algorithm_node; // ------------------------------------------------------------------------------------------------- // Constructors and destructors -LeadershipBroker::LeadershipBroker() { - this->network_leader_id = ""; -} +LeadershipBroker::LeadershipBroker() { this->network_leader_id = ""; } -LeadershipBroker::~LeadershipBroker() { -} +LeadershipBroker::~LeadershipBroker() {} shared_ptr LeadershipBroker::factory(LeadershipBrokerType instance_type) { switch (instance_type) { - case LeadershipBrokerType::SINGLE_MASTER_SERVER : { + case LeadershipBrokerType::SINGLE_MASTER_SERVER: { return shared_ptr(new SingleMasterServer()); } default: { @@ -25,34 +23,24 @@ shared_ptr LeadershipBroker::factory(LeadershipBrokerType inst } } -SingleMasterServer::SingleMasterServer() { -} +SingleMasterServer::SingleMasterServer() {} + +SingleMasterServer::~SingleMasterServer() {} -SingleMasterServer::~SingleMasterServer() { -} - // ------------------------------------------------------------------------------------------------- // Public superclass API -string LeadershipBroker::leader_id() { - return this->network_leader_id; -} +string LeadershipBroker::leader_id() { return this->network_leader_id; } -void LeadershipBroker::set_leader_id(const string &leader_id) { - this->network_leader_id = leader_id; -} +void LeadershipBroker::set_leader_id(const string& leader_id) { this->network_leader_id = leader_id; } -bool LeadershipBroker::has_leader() { - return (this->network_leader_id != ""); -} +bool LeadershipBroker::has_leader() { return (this->network_leader_id != ""); } void LeadershipBroker::set_message_broker(shared_ptr message_broker) { this->message_broker = message_broker; } - + // ------------------------------------------------------------------------------------------------- // Concrete implementation of abstract LeadershipBroker API -void SingleMasterServer::start_leader_election(const string &my_vote) { - this->set_leader_id(my_vote); -} +void SingleMasterServer::start_leader_election(const string& my_vote) { this->set_leader_id(my_vote); } diff --git a/src/distributed_algorithm_node/LeadershipBroker.h b/src/distributed_algorithm_node/LeadershipBroker.h index 54df65c..d908889 100644 --- a/src/distributed_algorithm_node/LeadershipBroker.h +++ b/src/distributed_algorithm_node/LeadershipBroker.h @@ -7,10 +7,7 @@ using namespace std; namespace distributed_algorithm_node { -enum class LeadershipBrokerType { - SINGLE_MASTER_SERVER -}; - +enum class LeadershipBrokerType { SINGLE_MASTER_SERVER }; // ------------------------------------------------------------------------------------------------- // Abstract superclass @@ -18,18 +15,17 @@ enum class LeadershipBrokerType { /** * Implements the algorithm for leader election. * - * This is the abstract class defining the API used by DistributedAlgorithmNodes to deal with leader election. - * Users of the DistributedAlgorithmNode module aren't supposed to interact with LeadershipBroker directly. + * This is the abstract class defining the API used by DistributedAlgorithmNodes + * to deal with leader election. Users of the DistributedAlgorithmNode module + * aren't supposed to interact with LeadershipBroker directly. */ class LeadershipBroker { - -public: - + public: /** * Factory method for concrete subclasses. * - * @param instance_type Defines which subclass should be used to instantiate the - * LeadershipBroker. + * @param instance_type Defines which subclass should be used to instantiate + * the LeadershipBroker. * @return An instance of the selected LeadershipBroker subclass. */ static shared_ptr factory(LeadershipBrokerType instance_type); @@ -47,7 +43,8 @@ class LeadershipBroker { /** * Sets MessageBroker to be used to communicate with peers. * - * @param message_broker The MessageBroker to be used to ciommunicate with peers. + * @param message_broker The MessageBroker to be used to ciommunicate with + * peers. */ void set_message_broker(shared_ptr message_broker); @@ -63,7 +60,7 @@ class LeadershipBroker { * * @param leader_id The leader node ID. */ - void set_leader_id(const string &leader_id); + void set_leader_id(const string& leader_id); /** * Return true iff a leader has been defined. @@ -76,13 +73,12 @@ class LeadershipBroker { /** * Starts an election to define the leader of the network. * - * @param my_vote The vote casted by the hosting node to tghe leadership election. + * @param my_vote The vote casted by the hosting node to tghe leadership + * election. */ - virtual void start_leader_election(const string &my_vote) = 0; - - -private: + virtual void start_leader_election(const string& my_vote) = 0; + private: shared_ptr message_broker; string network_leader_id; }; @@ -91,14 +87,12 @@ class LeadershipBroker { // Concrete subclasses /** - * Concrete implementation of a leadership selection algorithm based in a topology of one server - * connected to N clients, where clients only know about the server which is always the leader of - * the network. + * Concrete implementation of a leadership selection algorithm based in a + * topology of one server connected to N clients, where clients only know about + * the server which is always the leader of the network. */ class SingleMasterServer : public LeadershipBroker { - -public: - + public: /** * Basic constructor */ @@ -109,14 +103,12 @@ class SingleMasterServer : public LeadershipBroker { */ ~SingleMasterServer(); - // ---------------------------------------------------------------- // Public LeadershipBroker abstract API - void start_leader_election(const string &my_vote); + void start_leader_election(const string& my_vote); }; -} // namespace distributed_algorithm_node - -#endif // _DISTRIBUTED_ALGORITHM_NODE_LEADERSHIPBROKER_H +} // namespace distributed_algorithm_node +#endif // _DISTRIBUTED_ALGORITHM_NODE_LEADERSHIPBROKER_H diff --git a/src/distributed_algorithm_node/Message.cc b/src/distributed_algorithm_node/Message.cc index 10a1eb6..8a0436c 100644 --- a/src/distributed_algorithm_node/Message.cc +++ b/src/distributed_algorithm_node/Message.cc @@ -1,23 +1,19 @@ #include "Message.h" + #include "DistributedAlgorithmNode.h" using namespace distributed_algorithm_node; -Message::Message() { -} +Message::Message() {} -Message::~Message() { -} +Message::~Message() {} // ------------------------------------------------------------------------------------------------- // Specialized Message subclasses -NodeJoinedNetwork::~NodeJoinedNetwork() { -} +NodeJoinedNetwork::~NodeJoinedNetwork() {} -NodeJoinedNetwork::NodeJoinedNetwork(string &node_id) { - this->joining_node = node_id; -} +NodeJoinedNetwork::NodeJoinedNetwork(string& node_id) { this->joining_node = node_id; } void NodeJoinedNetwork::act(shared_ptr node) { auto distributed_algorithm_node = dynamic_pointer_cast(node); diff --git a/src/distributed_algorithm_node/Message.h b/src/distributed_algorithm_node/Message.h index 1b82651..48c7668 100644 --- a/src/distributed_algorithm_node/Message.h +++ b/src/distributed_algorithm_node/Message.h @@ -1,9 +1,9 @@ #ifndef _DISTRIBUTED_ALGORITHM_NODE_MESSAGE_H #define _DISTRIBUTED_ALGORITHM_NODE_MESSAGE_H +#include #include #include -#include using namespace std; @@ -13,13 +13,12 @@ class DistributedAlgorithmNode; class Message; /** - * Interface to be implemented by nodes (concrete implementations of DistributedAlgorithmNode) in order to - * provide a factory method for the types of messages defined in its specific network. + * Interface to be implemented by nodes (concrete implementations of + * DistributedAlgorithmNode) in order to provide a factory method for the types + * of messages defined in its specific network. */ class MessageFactory { - -public: - + public: /** * Message factory method. * @@ -27,7 +26,7 @@ class MessageFactory { * @param args Arguments for the command. * @return An object of the proper class to deal with the passed command. */ - virtual shared_ptr message_factory(string &command, vector &args) = 0; + virtual shared_ptr message_factory(string& command, vector& args) = 0; }; // ------------------------------------------------------------------------------------------------- @@ -36,24 +35,23 @@ class MessageFactory { /** * Basic abstract class for Messages to be exchanged among nodes in the network. * - * Concrete subclasses should implement the act() method to perform whatever operation is - * required in the recipient node. + * Concrete subclasses should implement the act() method to perform whatever + * operation is required in the recipient node. * - * Note that Message objects don't actually get serialized and sent through the network. - * What's actually sent is some identifier that makes possible for the recipients to - * know which concrete class of Message should be instantiated there. + * Note that Message objects don't actually get serialized and sent through the + * network. What's actually sent is some identifier that makes possible for the + * recipients to know which concrete class of Message should be instantiated + * there. * - * Once the recipient receives this identifier, it instantiates an object of the proper - * class (a concrete implementation of Message) and executed act(), passing the target - * node as parameter. + * Once the recipient receives this identifier, it instantiates an object of the + * proper class (a concrete implementation of Message) and executed act(), + * passing the target node as parameter. */ class Message { - -public: - + public: /** - * Executes the action defined in the Message in the recipient node, which is passed as - * parameter. + * Executes the action defined in the Message in the recipient node, which is + * passed as parameter. * * @param node The DistributedAlgorithmNode which received the Message. */ @@ -69,32 +67,28 @@ class Message { */ ~Message(); -private: - + private: }; // ------------------------------------------------------------------------------------------------- // Concrete Messages used in basic DistributedAlgorithmNode settings /** - * Concrete Message implementation to deal with command "node_join_network", used - * by DistributedAlgorithmNode to notify other nodes in the network of the presence of a newly - * joined node. + * Concrete Message implementation to deal with command "node_join_network", + * used by DistributedAlgorithmNode to notify other nodes in the network of the + * presence of a newly joined node. */ class NodeJoinedNetwork : public Message { - -private: - + private: string joining_node; -public: - + public: /** * Basic constructor. * * @param node_id ID of the newly joined node. */ - NodeJoinedNetwork(string &node_id); + NodeJoinedNetwork(string& node_id); /** * Destructor. @@ -107,6 +101,6 @@ class NodeJoinedNetwork : public Message { void act(shared_ptr node); }; -} // namespace distributed_algorithm_node +} // namespace distributed_algorithm_node -#endif // _DISTRIBUTED_ALGORITHM_NODE_MESSAGE_H +#endif // _DISTRIBUTED_ALGORITHM_NODE_MESSAGE_H diff --git a/src/distributed_algorithm_node/MessageBroker.cc b/src/distributed_algorithm_node/MessageBroker.cc index 5a146f2..90a5e84 100644 --- a/src/distributed_algorithm_node/MessageBroker.cc +++ b/src/distributed_algorithm_node/MessageBroker.cc @@ -1,55 +1,52 @@ -#include -#include -#include #include #include #include +#include +#include +#include #include - #include "common.pb.h" -// TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node +// TODO: Once das-proto is updated, update atom_space_node to +// distributed_algorithm_node // #include "distributed_algorithm_node.grpc.pb.h" // #include "distributed_algorithm_node.pb.h" +#include "MessageBroker.h" +#include "Utils.h" #include "atom_space_node.grpc.pb.h" #include "atom_space_node.pb.h" -#include "Utils.h" -#include "MessageBroker.h" - using namespace distributed_algorithm_node; unsigned int SynchronousGRPC::MESSAGE_THREAD_COUNT = 10; unsigned int SynchronousSharedRAM::MESSAGE_THREAD_COUNT = 1; -unordered_map SynchronousSharedRAM::NODE_QUEUE; +unordered_map SynchronousSharedRAM::NODE_QUEUE; mutex SynchronousSharedRAM::NODE_QUEUE_MUTEX; // ------------------------------------------------------------------------------------------------- // Constructors and destructors -shared_ptr MessageBroker::factory( - MessageBrokerType instance_type, - shared_ptr host_node, - const string &node_id) { - +shared_ptr MessageBroker::factory(MessageBrokerType instance_type, + shared_ptr host_node, + const string& node_id) { switch (instance_type) { - case MessageBrokerType::RAM : { + case MessageBrokerType::RAM: { return shared_ptr(new SynchronousSharedRAM(host_node, node_id)); } - case MessageBrokerType::GRPC : { + case MessageBrokerType::GRPC: { return shared_ptr(new SynchronousGRPC(host_node, node_id)); } default: { Utils::error("Invalid MessageBrokerType: " + to_string((int) instance_type)); - return shared_ptr{}; // to avoid warnings + return shared_ptr{}; // to avoid warnings } } } -MessageBroker::MessageBroker(shared_ptr host_node, const string &node_id) { - if (! host_node) { +MessageBroker::MessageBroker(shared_ptr host_node, const string& node_id) { + if (!host_node) { Utils::error("Invalid NULL host_node"); } this->host_node = host_node; @@ -58,17 +55,14 @@ MessageBroker::MessageBroker(shared_ptr host_node, const string this->joined_network = false; } -MessageBroker::~MessageBroker() { -} +MessageBroker::~MessageBroker() {} -SynchronousSharedRAM::SynchronousSharedRAM( - shared_ptr host_node, - const string &node_id) : MessageBroker(host_node, node_id) { -} +SynchronousSharedRAM::SynchronousSharedRAM(shared_ptr host_node, const string& node_id) + : MessageBroker(host_node, node_id) {} SynchronousSharedRAM::~SynchronousSharedRAM() { if (this->joined_network) { - for (auto thread: inbox_threads) { + for (auto thread : inbox_threads) { thread->join(); } NODE_QUEUE_MUTEX.lock(); @@ -82,16 +76,15 @@ SynchronousSharedRAM::~SynchronousSharedRAM() { } } -SynchronousGRPC::SynchronousGRPC( - shared_ptr host_node, - const string &node_id) : MessageBroker(host_node, node_id) { +SynchronousGRPC::SynchronousGRPC(shared_ptr host_node, const string& node_id) + : MessageBroker(host_node, node_id) { this->grpc_server_started_flag = false; this->inbox_setup_finished_flag = false; } SynchronousGRPC::~SynchronousGRPC() { if (this->joined_network) { - for (auto thread: inbox_threads) { + for (auto thread : inbox_threads) { thread->join(); } this->grpc_server->Shutdown(); @@ -116,28 +109,28 @@ void SynchronousGRPC::grpc_thread_method() { void SynchronousSharedRAM::inbox_thread_method() { bool stop_flag = false; do { - void *request = this->incoming_messages.dequeue(); + void* request = this->incoming_messages.dequeue(); if (request != NULL) { - CommandLinePackage *message_data = (CommandLinePackage *) request; + CommandLinePackage* message_data = (CommandLinePackage*) request; if (message_data->is_broadcast) { if (message_data->visited.find(this->node_id) != message_data->visited.end()) { continue; } this->peers_mutex.lock(); - for (auto target: this->peers) { + for (auto target : this->peers) { if (message_data->visited.find(target) == message_data->visited.end()) { - CommandLinePackage *command_line = new CommandLinePackage( - message_data->command, - message_data->args); + CommandLinePackage* command_line = + new CommandLinePackage(message_data->command, message_data->args); command_line->is_broadcast = true; command_line->visited = message_data->visited; command_line->visited.insert(this->node_id); - NODE_QUEUE[target]->enqueue((void *) command_line); + NODE_QUEUE[target]->enqueue((void*) command_line); } } this->peers_mutex.unlock(); } - std::shared_ptr message = this->host_node->message_factory(message_data->command, message_data->args); + std::shared_ptr message = + this->host_node->message_factory(message_data->command, message_data->args); if (message) { message->act(this->host_node); delete message_data; @@ -152,16 +145,16 @@ void SynchronousSharedRAM::inbox_thread_method() { Utils::sleep(); } } - } while (! stop_flag); + } while (!stop_flag); } void SynchronousGRPC::inbox_thread_method() { bool stop_flag = false; set_inbox_setup_finished(); do { - void *request = this->incoming_messages.dequeue(); + void* request = this->incoming_messages.dequeue(); if (request != NULL) { - dasproto::MessageData *message_data = (dasproto::MessageData *) request; + dasproto::MessageData* message_data = (dasproto::MessageData*) request; if (message_data->is_broadcast()) { this->peers_mutex.lock(); unsigned int num_peers = this->peers.size(); @@ -180,11 +173,14 @@ void SynchronousGRPC::inbox_thread_method() { } message_data->add_visited_recipients(this->node_id); this->peers_mutex.lock(); - for (auto target: this->peers) { + for (auto target : this->peers) { if (visited.find(target) == visited.end()) { - // TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node - // auto stub = dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(target, grpc::InsecureChannelCredentials())); - auto stub = dasproto::AtomSpaceNode::NewStub(grpc::CreateChannel(target, grpc::InsecureChannelCredentials())); + // TODO: Once das-proto is updated, update atom_space_node to + // distributed_algorithm_node auto stub = + // dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(target, + // grpc::InsecureChannelCredentials())); + auto stub = dasproto::AtomSpaceNode::NewStub( + grpc::CreateChannel(target, grpc::InsecureChannelCredentials())); stub->execute_message(&(context[cursor]), *message_data, &(reply[cursor])); cursor++; } @@ -212,19 +208,19 @@ void SynchronousGRPC::inbox_thread_method() { Utils::sleep(); } } - } while (! stop_flag); + } while (!stop_flag); } // ------------------------------------------------------------------------------------------------- // MessageBroker API -void MessageBroker::add_peer(const string &peer_id) { +void MessageBroker::add_peer(const string& peer_id) { peers_mutex.lock(); peers.insert(peer_id); peers_mutex.unlock(); } -bool MessageBroker::is_peer(const string &peer_id) { +bool MessageBroker::is_peer(const string& peer_id) { bool answer = true; this->peers_mutex.lock(); if (peers.find(peer_id) == peers.end()) { @@ -261,41 +257,37 @@ void SynchronousSharedRAM::join_network() { NODE_QUEUE_MUTEX.unlock(); } for (unsigned int i = 0; i < MESSAGE_THREAD_COUNT; i++) { - this->inbox_threads.push_back(new thread( - &SynchronousSharedRAM::inbox_thread_method, - this)); + this->inbox_threads.push_back(new thread(&SynchronousSharedRAM::inbox_thread_method, this)); } this->joined_network = true; } -void SynchronousSharedRAM::send( - const string &command, - const vector &args, - const string &recipient) { - - if (! this->is_shutting_down()) { - if (! is_peer(recipient)) { +void SynchronousSharedRAM::send(const string& command, + const vector& args, + const string& recipient) { + if (!this->is_shutting_down()) { + if (!is_peer(recipient)) { Utils::error("Unknown peer: " + recipient); } - CommandLinePackage *command_line = new CommandLinePackage(command, args); - NODE_QUEUE[recipient]->enqueue((void *) command_line); + CommandLinePackage* command_line = new CommandLinePackage(command, args); + NODE_QUEUE[recipient]->enqueue((void*) command_line); } } -void SynchronousSharedRAM::broadcast(const string &command, const vector &args) { - if (! this->is_shutting_down()) { +void SynchronousSharedRAM::broadcast(const string& command, const vector& args) { + if (!this->is_shutting_down()) { this->peers_mutex.lock(); unsigned int num_peers = this->peers.size(); if (num_peers == 0) { this->peers_mutex.unlock(); return; } - CommandLinePackage *command_line; - for (auto peer_id: this->peers) { + CommandLinePackage* command_line; + for (auto peer_id : this->peers) { command_line = new CommandLinePackage(command, args); command_line->is_broadcast = true; command_line->visited.insert(this->node_id); - NODE_QUEUE[peer_id]->enqueue((void *) command_line); + NODE_QUEUE[peer_id]->enqueue((void*) command_line); } this->peers_mutex.unlock(); } @@ -305,50 +297,43 @@ void SynchronousSharedRAM::broadcast(const string &command, const vector // SynchronousGRPC void SynchronousGRPC::join_network() { - this->grpc_thread = new std::thread( - &SynchronousGRPC::grpc_thread_method, - this); - while (! this->grpc_server_started()) { + this->grpc_thread = new std::thread(&SynchronousGRPC::grpc_thread_method, this); + while (!this->grpc_server_started()) { Utils::sleep(); } for (unsigned int i = 0; i < MESSAGE_THREAD_COUNT; i++) { - this->inbox_threads.push_back(new thread( - &SynchronousGRPC::inbox_thread_method, - this)); + this->inbox_threads.push_back(new thread(&SynchronousGRPC::inbox_thread_method, this)); } - while (! this->inbox_setup_finished()) { + while (!this->inbox_setup_finished()) { Utils::sleep(); } } -void SynchronousGRPC::add_peer(const string &peer_id) { - MessageBroker::add_peer(peer_id); -} - -void SynchronousGRPC::send( - const string &command, - const vector &args, - const string &recipient) { +void SynchronousGRPC::add_peer(const string& peer_id) { MessageBroker::add_peer(peer_id); } - if (! is_peer(recipient)) { +void SynchronousGRPC::send(const string& command, const vector& args, const string& recipient) { + if (!is_peer(recipient)) { Utils::error("Unknown peer: " + recipient); } dasproto::MessageData message_data; message_data.set_command(command); - for (auto arg: args) { + for (auto arg : args) { message_data.add_args(arg); } message_data.set_sender(this->node_id); message_data.set_is_broadcast(false); dasproto::Empty reply; grpc::ClientContext context; - // TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node - // auto stub = dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(recipient, grpc::InsecureChannelCredentials())); - auto stub = dasproto::AtomSpaceNode::NewStub(grpc::CreateChannel(recipient, grpc::InsecureChannelCredentials())); + // TODO: Once das-proto is updated, update atom_space_node to + // distributed_algorithm_node auto stub = + // dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(recipient, + // grpc::InsecureChannelCredentials())); + auto stub = dasproto::AtomSpaceNode::NewStub( + grpc::CreateChannel(recipient, grpc::InsecureChannelCredentials())); stub->execute_message(&context, message_data, &reply); } -void SynchronousGRPC::broadcast(const string &command, const vector &args) { +void SynchronousGRPC::broadcast(const string& command, const vector& args) { this->peers_mutex.lock(); unsigned int num_peers = this->peers.size(); if (num_peers == 0) { @@ -358,18 +343,21 @@ void SynchronousGRPC::broadcast(const string &command, const vector &arg dasproto::Empty reply[num_peers]; grpc::ClientContext context[num_peers]; unsigned int cursor = 0; - for (auto peer_id: this->peers) { + for (auto peer_id : this->peers) { dasproto::MessageData message_data; message_data.set_command(command); - for (auto arg: args) { + for (auto arg : args) { message_data.add_args(arg); } message_data.set_sender(this->node_id); message_data.set_is_broadcast(true); message_data.add_visited_recipients(this->node_id); - // TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node - // auto stub = dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(peer_id, grpc::InsecureChannelCredentials())); - auto stub = dasproto::AtomSpaceNode::NewStub(grpc::CreateChannel(peer_id, grpc::InsecureChannelCredentials())); + // TODO: Once das-proto is updated, update atom_space_node to + // distributed_algorithm_node auto stub = + // dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(peer_id, + // grpc::InsecureChannelCredentials())); + auto stub = dasproto::AtomSpaceNode::NewStub( + grpc::CreateChannel(peer_id, grpc::InsecureChannelCredentials())); stub->execute_message(&(context[cursor]), message_data, &(reply[cursor])); cursor++; } @@ -411,27 +399,23 @@ bool SynchronousGRPC::inbox_setup_finished() { // ------------------------------------------------------------------------------------------------- // GRPC Server API -grpc::Status SynchronousGRPC::ping( - grpc::ServerContext* grpc_context, - const dasproto::Empty* request, - dasproto::Ack* reply) { - +grpc::Status SynchronousGRPC::ping(grpc::ServerContext* grpc_context, + const dasproto::Empty* request, + dasproto::Ack* reply) { reply->set_msg("PING"); - if (! this->is_shutting_down()) { + if (!this->is_shutting_down()) { return grpc::Status::OK; } else { return grpc::Status::CANCELLED; } } -grpc::Status SynchronousGRPC::execute_message( - grpc::ServerContext* grpc_context, - const dasproto::MessageData* request, - dasproto::Empty* reply) { - - if (! this->is_shutting_down()) { +grpc::Status SynchronousGRPC::execute_message(grpc::ServerContext* grpc_context, + const dasproto::MessageData* request, + dasproto::Empty* reply) { + if (!this->is_shutting_down()) { // TODO: fix memory leak - this->incoming_messages.enqueue((void *) new dasproto::MessageData(*request)); + this->incoming_messages.enqueue((void*) new dasproto::MessageData(*request)); return grpc::Status::OK; } else { return grpc::Status::CANCELLED; @@ -441,11 +425,10 @@ grpc::Status SynchronousGRPC::execute_message( // ------------------------------------------------------------------------------------------------- // Common utility classes -CommandLinePackage::CommandLinePackage(const string &command, const vector &args) { +CommandLinePackage::CommandLinePackage(const string& command, const vector& args) { this->command = command; this->args = args; this->is_broadcast = false; } -CommandLinePackage::~CommandLinePackage() { -} +CommandLinePackage::~CommandLinePackage() {} diff --git a/src/distributed_algorithm_node/MessageBroker.h b/src/distributed_algorithm_node/MessageBroker.h index 3c78cbc..2ee6814 100644 --- a/src/distributed_algorithm_node/MessageBroker.h +++ b/src/distributed_algorithm_node/MessageBroker.h @@ -1,13 +1,14 @@ #ifndef _DISTRIBUTED_ALGORITHM_NODE_MESSAGEBROKER_H #define _DISTRIBUTED_ALGORITHM_NODE_MESSAGEBROKER_H -#include -#include +#include #include #include -#include +#include +#include -// TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node +// TODO: Once das-proto is updated, update atom_space_node to +// distributed_algorithm_node #include "atom_space_node.grpc.pb.h" // #include "distributed_algorithm_node.grpc.pb.h" @@ -20,10 +21,7 @@ using namespace commons; namespace distributed_algorithm_node { -enum class MessageBrokerType { - RAM, - GRPC -}; +enum class MessageBrokerType { RAM, GRPC }; class DistributedAlgorithmNode; @@ -33,35 +31,36 @@ class DistributedAlgorithmNode; /** * Implements the communication layer used by nodes to exchange Messages. * - * This is the abstract class defining the API used by DistributedAlgorithmNodes to exchange messages. - * Users of the DistributedAlgorithmNode module aren't supposed to interact with MessageBroker directly. + * This is the abstract class defining the API used by DistributedAlgorithmNodes + * to exchange messages. Users of the DistributedAlgorithmNode module aren't + * supposed to interact with MessageBroker directly. */ class MessageBroker { - -public: - + public: /** * Factory method for concrete subclasses. * - * @param instance_type Defines which subclass should be used to instantiate the MessageBroker - * @param host_node The object responsible for building Message objects. Typically, it's The - * node this MessageBroker belongs to. - * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker belongs to. + * @param instance_type Defines which subclass should be used to instantiate + * the MessageBroker + * @param host_node The object responsible for building Message objects. + * Typically, it's The node this MessageBroker belongs to. + * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker + * belongs to. * @return An instance of the selected MessageBroker subclass. */ - static shared_ptr factory( - MessageBrokerType instance_type, - shared_ptr host_node, - const string &node_id); + static shared_ptr factory(MessageBrokerType instance_type, + shared_ptr host_node, + const string& node_id); /** * Basic constructor * - * @param host_node The object responsible for building Message objects. Typically, it's The - * node this MessageBroker belongs to. - * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker belongs to. + * @param host_node The object responsible for building Message objects. + * Typically, it's The node this MessageBroker belongs to. + * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker + * belongs to. */ - MessageBroker(shared_ptr host_node, const string &node_id); + MessageBroker(shared_ptr host_node, const string& node_id); /** * Destructor. @@ -76,7 +75,7 @@ class MessageBroker { * * @param peer_id The ID of the newly known peer. */ - virtual void add_peer(const string &peer_id); + virtual void add_peer(const string& peer_id); /** * Returns true iff the passed peer has been previously added @@ -84,18 +83,20 @@ class MessageBroker { * @param peer_id Peer id being checked. * @return true iff the passed peer has been previously added */ - bool is_peer(const string &peer_id); + bool is_peer(const string& peer_id); /** - * Gracefully shuts down threads or any other resources being used in communication. + * Gracefully shuts down threads or any other resources being used in + * communication. */ void graceful_shutdown(); /** * Returns true iff this MessageBroker is shuting down. * - * The idea is to allow concrete subclasses to know when a graceful shutdown has been requested - * so threads or any other resources being used in communication can be stoped/released/etc. + * The idea is to allow concrete subclasses to know when a graceful shutdown + * has been requested so threads or any other resources being used in + * communication can be stoped/released/etc. */ bool is_shutting_down(); @@ -110,27 +111,25 @@ class MessageBroker { /** * Broadcasts a command to all nodes in the network. * - * All nodes in the network will be reached (not only the known peers) and the command - * will be executed. + * All nodes in the network will be reached (not only the known peers) and the + * command will be executed. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. */ - virtual void broadcast(const string &command, const vector &args) = 0; + virtual void broadcast(const string& command, const vector& args) = 0; /** * Sends a command to the passed node. * - * The target node is supposed to be a known peer. If not, an exception is thrown. + * The target node is supposed to be a known peer. If not, an exception is + * thrown. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. * @recipient The target node for the command. */ - virtual void send( - const string &command, - const vector &args, - const string &recipient) = 0; + virtual void send(const string& command, const vector& args, const string& recipient) = 0; shared_ptr host_node; unordered_set peers; @@ -145,22 +144,20 @@ class MessageBroker { // Concrete subclasses /** - * Concrete implementation of MessageBroker using shared queues in RAM to exchange Message among - * nodes. + * Concrete implementation of MessageBroker using shared queues in RAM to + * exchange Message among nodes. * * Nodes are supposed to be running in the same runtime process. */ class SynchronousSharedRAM : public MessageBroker { - -public: - + public: /** * Basic constructor * - * @param host_node The object responsible for building Message objects. Typically, it's The - * node this MessageBroker belongs to. + * @param host_node The object responsible for building Message objects. + * Typically, it's The node this MessageBroker belongs to. */ - SynchronousSharedRAM(shared_ptr host_node, const string &node_id); + SynchronousSharedRAM(shared_ptr host_node, const string& node_id); /** * Destructor. @@ -180,52 +177,54 @@ class SynchronousSharedRAM : public MessageBroker { /** * Broadcasts a command to all nodes in the network. * - * All nodes in the network will be reached (not only the known peers) and the command - * will be executed. Basically the Message is sent to all known peers which, in their turns, - * re-send it to their known peers until there's no other peer to spread it. The GRPC object - * used to send the request contains a list of visited nodes so a request is never re-sent - * to nodes that have already received it. + * All nodes in the network will be reached (not only the known peers) and the + * command will be executed. Basically the Message is sent to all known peers + * which, in their turns, re-send it to their known peers until there's no + * other peer to spread it. The GRPC object used to send the request contains + * a list of visited nodes so a request is never re-sent to nodes that have + * already received it. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. */ - virtual void broadcast(const string &command, const vector &args); + virtual void broadcast(const string& command, const vector& args); /** * Sends a command to the passed node. * - * The target node is supposed to be a known peer. If not, an exception is thrown. - * Uses the client GRPC channel to send the command to the target. + * The target node is supposed to be a known peer. If not, an exception is + * thrown. Uses the client GRPC channel to send the command to the target. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. * @recipient The target node for the command. */ - virtual void send(const string &command, const vector &args, const string &recipient); - -private: + virtual void send(const string& command, const vector& args, const string& recipient); + private: static unsigned int MESSAGE_THREAD_COUNT; - static unordered_map NODE_QUEUE; + static unordered_map NODE_QUEUE; static mutex NODE_QUEUE_MUTEX; - vector inbox_threads; - SharedQueue incoming_messages; // Thread safe container + vector inbox_threads; + SharedQueue incoming_messages; // Thread safe container // Methods used to start threads void inbox_thread_method(); }; /** - * Concrete implementation of MessageBroker using GRPC to exchange Message among nodes. + * Concrete implementation of MessageBroker using GRPC to exchange Message among + * nodes. * - * Synchronous GRPS calls are used to send commands between nodes in the network. When joining - * the network, each node initializes a request queue and a thread to listen to a PORT for - * GRPC calls (this thread is what GRPC's documentation calls a GRPC Server). This way this node - * becomes capable of answering GRPC requests. + * Synchronous GRPS calls are used to send commands between nodes in the + * network. When joining the network, each node initializes a request queue and + * a thread to listen to a PORT for GRPC calls (this thread is what GRPC's + * documentation calls a GRPC Server). This way this node becomes capable of + * answering GRPC requests. * - * In addition to this, another queue is initialized for outgoing Messages and another thread is - * started to observe this queue. + * In addition to this, another queue is initialized for outgoing Messages and + * another thread is started to observe this queue. * * A Client GRPC channel is created for each the newly inserted peer. * @@ -235,37 +234,38 @@ class SynchronousSharedRAM : public MessageBroker { * - A GRPC thread listening for the rpc command requests * - N threads reading from this queue and processing the requested commands. * - An outgoing queue with waiting-to-be-sent outgoing commands - * - N threads observing the outgoing queue and processing this queue to send requests to other - * nodes. + * - N threads observing the outgoing queue and processing this queue to send + * requests to other nodes. * - * When one of the methods to send messages is called (e.g. broadcast() or send()), the passed - * command is enqueued in the outgoing queue and the methoid returns immetialely, meaning that that - * is no guarantee that the Message have been received by the other node(s) when the method returns. - * A thread will dequeue the request and use a previously created client GRPC channel to make the - * GRPC rpc call, sending the command to the target node. + * When one of the methods to send messages is called (e.g. broadcast() or + * send()), the passed command is enqueued in the outgoing queue and the methoid + * returns immetialely, meaning that that is no guarantee that the Message have + * been received by the other node(s) when the method returns. A thread will + * dequeue the request and use a previously created client GRPC channel to make + * the GRPC rpc call, sending the command to the target node. * - * In the target node, the GRPC server thread will get the requested command and enequeue it in the - * incomming queue. Then a thread will dequeue this request and execute the requested command on - * the target node. + * In the target node, the GRPC server thread will get the requested command and + * enequeue it in the incomming queue. Then a thread will dequeue this request + * and execute the requested command on the target node. * - * No rpc answer is used in these GRPC calls. So if a command expects an answer to return, this - * answer is supposed to be implemented as a separate Message going back from the target node to - * the node that originated the request. + * No rpc answer is used in these GRPC calls. So if a command expects an answer + * to return, this answer is supposed to be implemented as a separate Message + * going back from the target node to the node that originated the request. */ -// TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node -// class SynchronousGRPC : public MessageBroker, public dasproto::DistributedAlgorithmNode::Service { +// TODO: Once das-proto is updated, update atom_space_node to +// distributed_algorithm_node class SynchronousGRPC : public MessageBroker, +// public dasproto::DistributedAlgorithmNode::Service { class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Service { - -public: - + public: /** * Basic constructor * - * @param host_node The object responsible for building Message objects. Typically, it's The - * node this MessageBroker belongs to. - * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker belongs to. + * @param host_node The object responsible for building Message objects. + * Typically, it's The node this MessageBroker belongs to. + * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker + * belongs to. */ - SynchronousGRPC(shared_ptr host_node, const string &node_id); + SynchronousGRPC(shared_ptr host_node, const string& node_id); /** * Destructor. @@ -273,13 +273,13 @@ class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Se ~SynchronousGRPC(); /** - * Adds additional processing to superclass' add_peer() basically only adds the new peer id - * into a container. Here, a GRPC channel is created and stored in the object for further use - * when sending Messages. + * Adds additional processing to superclass' add_peer() basically only adds + * the new peer id into a container. Here, a GRPC channel is created and + * stored in the object for further use when sending Messages. * * @param peer_id The ID of the newly known peer. */ - virtual void add_peer(const string &peer_id); + virtual void add_peer(const string& peer_id); // ---------------------------------------------------------------- // Public MessageBroker abstract API @@ -287,36 +287,38 @@ class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Se /** * Inserts the host node into the network. * - * Initialize incoming and outgoing queues and starts threads to process each of them. - * Also initializes the GRPC Server thread to listen to the GRPC calls. + * Initialize incoming and outgoing queues and starts threads to process each + * of them. Also initializes the GRPC Server thread to listen to the GRPC + * calls. */ virtual void join_network(); /** * Broadcasts a command to all nodes in the network. * - * All nodes in the network will be reached (not only the known peers) and the command - * will be executed. Basically the Message is sent to all known peers which, in their turns, - * re-send it to their known peers until there's no other peer to spread it. The GRPC object - * used to send the request contains a list of visited nodes so a request is never re-sent - * to nodes that have already received it. + * All nodes in the network will be reached (not only the known peers) and the + * command will be executed. Basically the Message is sent to all known peers + * which, in their turns, re-send it to their known peers until there's no + * other peer to spread it. The GRPC object used to send the request contains + * a list of visited nodes so a request is never re-sent to nodes that have + * already received it. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. */ - virtual void broadcast(const string &command, const vector &args); + virtual void broadcast(const string& command, const vector& args); /** * Sends a command to the passed node. * - * The target node is supposed to be a known peer. If not, an exception is thrown. - * Uses the client GRPC channel to send the command to the target. + * The target node is supposed to be a known peer. If not, an exception is + * thrown. Uses the client GRPC channel to send the command to the target. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. * @recipient The target node for the command. */ - virtual void send(const string &command, const vector &args, const string &recipient); + virtual void send(const string& command, const vector& args, const string& recipient); // ---------------------------------------------------------------- // Public GRPC API @@ -326,27 +328,24 @@ class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Se * * This is a standard rpc in DAS proto which all servers implement. */ - grpc::Status ping( - grpc::ServerContext* grpc_context, - const dasproto::Empty* request, - dasproto::Ack* reply) override; + grpc::Status ping(grpc::ServerContext* grpc_context, + const dasproto::Empty* request, + dasproto::Ack* reply) override; /** * Delivers a Message to be remotely executed. */ - grpc::Status execute_message( - grpc::ServerContext* grpc_context, - const dasproto::MessageData* request, - dasproto::Empty* reply) override; - -private: + grpc::Status execute_message(grpc::ServerContext* grpc_context, + const dasproto::MessageData* request, + dasproto::Empty* reply) override; + private: static unsigned int MESSAGE_THREAD_COUNT; unique_ptr grpc_server; - thread *grpc_thread; - vector inbox_threads; - SharedQueue incoming_messages; // Thread safe container - SharedQueue outgoing_messages; // Thread safe container + thread* grpc_thread; + vector inbox_threads; + SharedQueue incoming_messages; // Thread safe container + SharedQueue outgoing_messages; // Thread safe container bool grpc_server_started_flag; mutex grpc_server_started_flag_mutex; @@ -366,16 +365,15 @@ class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Se // Common utility classes class CommandLinePackage { - public: - CommandLinePackage(const string &command, const vector &args); - ~CommandLinePackage(); - string command; - vector args; - bool is_broadcast; - unordered_set visited; + public: + CommandLinePackage(const string& command, const vector& args); + ~CommandLinePackage(); + string command; + vector args; + bool is_broadcast; + unordered_set visited; }; -} // namespace distributed_algorithm_node - -#endif // _DISTRIBUTED_ALGORITHM_NODE_MESSAGEBROKER_H +} // namespace distributed_algorithm_node +#endif // _DISTRIBUTED_ALGORITHM_NODE_MESSAGEBROKER_H diff --git a/src/docker/Dockerfile b/src/docker/Dockerfile index 36955bc..d5d1da9 100644 --- a/src/docker/Dockerfile +++ b/src/docker/Dockerfile @@ -20,7 +20,7 @@ RUN mkdir -p \ RUN yes | apt update -y \ && yes | apt install -y git build-essential curl protobuf-compiler python3 python3-pip cmake \ - libevent-dev libssl-dev pkg-config \ + libevent-dev libssl-dev pkg-config libncurses5\ && yes | apt clean -y \ && rm -rf /var/lib/apt/lists/* diff --git a/src/hasher/expression_hasher.cc b/src/hasher/expression_hasher.cc index 53f331e..3287c37 100644 --- a/src/hasher/expression_hasher.cc +++ b/src/hasher/expression_hasher.cc @@ -1,14 +1,16 @@ -#include +#include "expression_hasher.h" + #include +#include #include + #include "mbedtls/md5.h" -#include "expression_hasher.h" static unsigned char MD5_BUFFER[16]; static char HASH[HANDLE_HASH_SIZE]; static char HASHABLE_STRING[MAX_HASHABLE_STRING_SIZE]; -char *compute_hash(char *input) { +char* compute_hash(char* input) { mbedtls_md5_context context; mbedtls_md5_init(&context); mbedtls_md5_starts(&context); @@ -16,17 +18,15 @@ char *compute_hash(char *input) { mbedtls_md5_finish(&context, MD5_BUFFER); mbedtls_md5_free(&context); for (unsigned int i = 0; i < 16; i++) { - sprintf((char *) ((unsigned long) HASH + 2 * i), "%02x", MD5_BUFFER[i]); + sprintf((char*) ((unsigned long) HASH + 2 * i), "%02x", MD5_BUFFER[i]); } HASH[32] = '\0'; return strdup(HASH); } -char *named_type_hash(char *name) { - return compute_hash(name); -} +char* named_type_hash(char* name) { return compute_hash(name); } -char *terminal_hash(char *type, char *name) { +char* terminal_hash(char* type, char* name) { if (strlen(type) + strlen(name) >= MAX_HASHABLE_STRING_SIZE) { fprintf(stderr, "Invalid (too large) terminal name"); exit(1); @@ -35,8 +35,7 @@ char *terminal_hash(char *type, char *name) { return compute_hash(HASHABLE_STRING); } -char *composite_hash(char **elements, unsigned int nelements) { - +char* composite_hash(char** elements, unsigned int nelements) { unsigned int total_size = 0; unsigned int element_size[nelements]; @@ -57,9 +56,9 @@ char *composite_hash(char **elements, unsigned int nelements) { unsigned long cursor = 0; for (unsigned int i = 0; i < nelements; i++) { if (i == (nelements - 1)) { - strcpy((char *) (HASHABLE_STRING + cursor), elements[i]); + strcpy((char*) (HASHABLE_STRING + cursor), elements[i]); } else { - sprintf((char *) (HASHABLE_STRING + cursor), "%s%c", elements[i], JOINING_CHAR); + sprintf((char*) (HASHABLE_STRING + cursor), "%s%c", elements[i], JOINING_CHAR); cursor += 1; } cursor += element_size[i]; @@ -68,8 +67,8 @@ char *composite_hash(char **elements, unsigned int nelements) { return compute_hash(HASHABLE_STRING); } -char *expression_hash(char *type_hash, char **elements, unsigned int nelements) { - char *composite[nelements + 1]; +char* expression_hash(char* type_hash, char** elements, unsigned int nelements) { + char* composite[nelements + 1]; composite[0] = type_hash; for (unsigned int i = 0; i < nelements; i++) { composite[i + 1] = elements[i]; diff --git a/src/hasher/expression_hasher.h b/src/hasher/expression_hasher.h index 78d309f..7f795d9 100644 --- a/src/hasher/expression_hasher.h +++ b/src/hasher/expression_hasher.h @@ -1,15 +1,15 @@ #ifndef EXPRESSIONHASHER_H #define EXPRESSIONHASHER_H -#define JOINING_CHAR ((char ) ' ') +#define JOINING_CHAR ((char) ' ') #define MAX_LITERAL_OR_SYMBOL_SIZE ((size_t) 10000) #define MAX_HASHABLE_STRING_SIZE ((size_t) 100000) #define HANDLE_HASH_SIZE ((unsigned int) 33) -char *compute_hash(char *input); -char *named_type_hash(char *name); -char *terminal_hash(char *type, char *name); -char *expression_hash(char *type_hash, char **elements, unsigned int nelements); -char *composite_hash(char **elements, unsigned int nelements); +char* compute_hash(char* input); +char* named_type_hash(char* name); +char* terminal_hash(char* type, char* name); +char* expression_hash(char* type_hash, char** elements, unsigned int nelements); +char* composite_hash(char** elements, unsigned int nelements); #endif diff --git a/src/hyperon_das_atomdb_cpp/atom_db_publicist.h b/src/hyperon_das_atomdb_cpp/atom_db_publicist.h index b2de6eb..12e899e 100644 --- a/src/hyperon_das_atomdb_cpp/atom_db_publicist.h +++ b/src/hyperon_das_atomdb_cpp/atom_db_publicist.h @@ -6,15 +6,17 @@ using namespace atomdb; /** * @class AtomDBPublicist - * @brief A publicist class for AtomDB that exposes certain protected member functions. + * @brief A publicist class for AtomDB that exposes certain protected member + * functions. * - * This class inherits from AtomDB and makes the following protected member functions - * accessible publicly: + * This class inherits from AtomDB and makes the following protected member + * functions accessible publicly: * - _build_link * - _build_node * - _get_atom * - * This can be useful for testing or other purposes where access to these functions is required. + * This can be useful for testing or other purposes where access to these + * functions is required. */ class AtomDBPublicist : public AtomDB { public: diff --git a/src/hyperon_das_atomdb_cpp/bind_helpers.h b/src/hyperon_das_atomdb_cpp/bind_helpers.h index 04161e3..9195e0c 100644 --- a/src/hyperon_das_atomdb_cpp/bind_helpers.h +++ b/src/hyperon_das_atomdb_cpp/bind_helpers.h @@ -1,23 +1,27 @@ /** * @file bind_helpers.h - * @brief This header file contains helper functions and type definitions for binding C++ - * classes and structures to Python using the `nanobind` library. The primary purpose - * of these helpers is to facilitate the conversion of C++ objects to Python objects - * and vice versa, enabling seamless interoperability between the two languages. + * @brief This header file contains helper functions and type definitions for + * binding C++ classes and structures to Python using the `nanobind` library. + * The primary purpose of these helpers is to facilitate the conversion of C++ + * objects to Python objects and vice versa, enabling seamless interoperability + * between the two languages. * * The file includes: * - Type definitions for tuples representing various C++ structures. - * - Functions for converting between C++ and Python representations of these structures. - * - Functions for converting composite types between C++ lists and Python lists. + * - Functions for converting between C++ and Python representations of these + * structures. + * - Functions for converting composite types between C++ lists and Python + * lists. * - Functions for converting C++ objects to Python dictionaries. - * - Functions for initializing and updating C++ objects from Python representations. + * - Functions for initializing and updating C++ objects from Python + * representations. */ #pragma once #include #include -#include #include +#include using namespace std; using namespace atomdb; @@ -54,7 +58,8 @@ using LinkTuple = // Tuple for Link /** * @brief Converts a composite type list to a Python list. * @param ct_list The composite type list to be converted. - * @return A Python list (`nb::list`) containing the elements of the composite type list. + * @return A Python list (`nb::list`) containing the elements of the composite + * type list. */ static nb::list composite_type_to_pylist(const ListOfAny& ct_list) { nb::list py_list; @@ -73,7 +78,8 @@ static nb::list composite_type_to_pylist(const ListOfAny& ct_list) { /** * @brief Converts a Python list to a composite type list. * @param py_list The Python list to be converted. - * @return A composite type list (`ListOfAny`) containing the elements of the Python list. + * @return A composite type list (`ListOfAny`) containing the elements of the + * Python list. */ static ListOfAny pylist_to_composite_type(const nb::list& py_list) { ListOfAny ct_list; @@ -95,7 +101,8 @@ static ListOfAny pylist_to_composite_type(const nb::list& py_list) { /** * @brief Converts an Atom object to a Python dictionary. * @param self The Atom object to be converted. - * @return A Python dictionary (`nb::dict`) containing the attributes of the Atom. + * @return A Python dictionary (`nb::dict`) containing the attributes of the + * Atom. */ static nb::dict atom_to_dict(const Atom& self) { nb::dict dict; @@ -110,7 +117,8 @@ static nb::dict atom_to_dict(const Atom& self) { /** * @brief Converts a Node object to a Python dictionary. * @param self The Node object to be converted. - * @return A Python dictionary (`nb::dict`) containing the attributes of the Node. + * @return A Python dictionary (`nb::dict`) containing the attributes of the + * Node. */ static nb::dict node_to_dict(const Node& self) { nb::dict dict = atom_to_dict(self); @@ -121,7 +129,8 @@ static nb::dict node_to_dict(const Node& self) { /** * @brief Converts a Link object to a Python dictionary. * @param self The Link object to be converted. - * @return A Python dictionary (`nb::dict`) containing the attributes of the Link. + * @return A Python dictionary (`nb::dict`) containing the attributes of the + * Link. */ static nb::dict link_to_dict(const Link& self) { nb::dict dict = atom_to_dict(self); diff --git a/src/hyperon_das_atomdb_cpp/hyperon_das_atomdb_cpp_bind.cc b/src/hyperon_das_atomdb_cpp/hyperon_das_atomdb_cpp_bind.cc index 01ac0e4..e98ce6c 100644 --- a/src/hyperon_das_atomdb_cpp/hyperon_das_atomdb_cpp_bind.cc +++ b/src/hyperon_das_atomdb_cpp/hyperon_das_atomdb_cpp_bind.cc @@ -30,7 +30,8 @@ using namespace nb::literals; NB_MODULE(ext, m) { // --------------------------------------------------------------------------------------------- - // constants submodule ------------------------------------------------------------------------- + // constants submodule + // ------------------------------------------------------------------------- nb::module_ constants = m.def_submodule("constants"); constants.attr("WILDCARD") = WILDCARD; constants.attr("WILDCARD_HASH") = WILDCARD_HASH; @@ -55,7 +56,8 @@ NB_MODULE(ext, m) { .def_ro_static("TARGETS_DOCUMENTS", &FieldNames::TARGETS_DOCUMENTS) .def_ro_static("CUSTOM_ATTRIBUTES", &FieldNames::CUSTOM_ATTRIBUTES); // --------------------------------------------------------------------------------------------- - // database submodule -------------------------------------------------------------------------- + // database submodule + // -------------------------------------------------------------------------- nb::module_ database = m.def_submodule("database"); nb::class_(database, "AtomDB") .def(nb::init<>()) @@ -264,14 +266,16 @@ NB_MODULE(ext, m) { .def("_build_link", &AtomDBPublicist::_build_link, "link_params"_a, "is_toplevel"_a = true) .def("_get_atom", &AtomDBPublicist::_get_atom, "handle"_a); // --------------------------------------------------------------------------------------------- - // adapters submodule -------------------------------------------------------------------------- + // adapters submodule + // -------------------------------------------------------------------------- nb::module_ adapters = m.def_submodule("adapters"); nb::class_(adapters, "InMemoryDB") .def(nb::init(), "database_name"_a = "das") .def("__repr__", [](const InMemoryDB& self) -> string { return ""; }) .def("__str__", [](const InMemoryDB& self) -> string { return ""; }); // --------------------------------------------------------------------------------------------- - // exceptions submodule ------------------------------------------------------------------------ + // exceptions submodule + // ------------------------------------------------------------------------ nb::module_ exceptions = m.def_submodule("exceptions"); nb::exception(exceptions, "AtomDbBaseException"); nb::exception(exceptions, "AddLinkException"); @@ -281,7 +285,8 @@ NB_MODULE(ext, m) { nb::exception(exceptions, "InvalidOperationException"); nb::exception(exceptions, "RetryException"); // --------------------------------------------------------------------------------------------- - // document_types submodule -------------------------------------------------------------------- + // document_types submodule + // -------------------------------------------------------------------- nb::module_ document_types = m.def_submodule("document_types"); nb::class_(document_types, "Atom") .def_rw("_id", &Atom::_id) @@ -298,9 +303,9 @@ NB_MODULE(ext, m) { nb::class_(document_types, "Node") .def( /** - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Node objects, use the - * constructor with all parameters. + * @note This constructor is intended to be used only when passing in + * the basic building parameters to other functions. For creating + * complete new Node objects, use the constructor with all parameters. */ nb::init(document_types, "Link") .def( /** - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Link objects, use the - * constructor with all parameters. + * @note This constructor is intended to be used only when passing in + * the basic building parameters to other functions. For creating + * complete new Link objects, use the constructor with all parameters. */ nb::init AtomDB::_reformat_document(const shared_ptr AtomDB::_build_node(const Node& node_params) { diff --git a/src/hyperon_das_atomdb_cpp_lib/database.h b/src/hyperon_das_atomdb_cpp_lib/database.h index dbbba8e..29acc2c 100644 --- a/src/hyperon_das_atomdb_cpp_lib/database.h +++ b/src/hyperon_das_atomdb_cpp_lib/database.h @@ -2,10 +2,11 @@ * @file database.h * @brief Abstract base class for the AtomDB database interface. * - * This header file defines the AtomDB class, which serves as an abstract base class for - * interacting with the AtomDB database. The AtomDB class provides a comprehensive interface - * for querying, adding, and managing atoms, nodes, and links within the database. Derived - * classes must implement the pure virtual methods to provide concrete functionality. + * This header file defines the AtomDB class, which serves as an abstract base + * class for interacting with the AtomDB database. The AtomDB class provides a + * comprehensive interface for querying, adding, and managing atoms, nodes, and + * links within the database. Derived classes must implement the pure virtual + * methods to provide concrete functionality. * * The AtomDB interface supports various operations, including: * - Retrieving atoms by different criteria (e.g., field, index, text field). @@ -13,19 +14,20 @@ * - Reindexing the database and creating field indexes. * - Bulk inserting atoms and committing changes. * - * The class is designed to be extended by specific database implementations, allowing for - * flexible and customizable database interactions. It includes static methods for building - * node and link handles, as well as methods for checking the existence of nodes and links, - * retrieving atoms, and reformatting documents. + * The class is designed to be extended by specific database implementations, + * allowing for flexible and customizable database interactions. It includes + * static methods for building node and link handles, as well as methods for + * checking the existence of nodes and links, retrieving atoms, and reformatting + * documents. * - * The AtomDB class also defines several pure virtual methods that must be implemented by - * derived classes. These methods cover a wide range of database operations, such as - * retrieving node handles, querying the database by field or text, managing links, - * reindexing, and more. + * The AtomDB class also defines several pure virtual methods that must be + * implemented by derived classes. These methods cover a wide range of database + * operations, such as retrieving node handles, querying the database by field + * or text, managing links, reindexing, and more. * - * @note This class uses several custom types and utility classes, such as StringList, - * ExpressionHasher, NodeParams, LinkParams, and KwArgs, which are defined elsewhere - * in the project. + * @note This class uses several custom types and utility classes, such as + * StringList, ExpressionHasher, NodeParams, LinkParams, and KwArgs, which are + * defined elsewhere in the project. */ #pragma once @@ -41,11 +43,12 @@ using namespace std; namespace atomdb { /** - * @brief A Plain Old Data (POD) type representing various boolean flags for configuration options. + * @brief A Plain Old Data (POD) type representing various boolean flags for + * configuration options. * - * This structure contains several boolean flags that control different aspects of the - * configuration, such as target formatting, document handling, representation depth, - * and scope of operation. + * This structure contains several boolean flags that control different aspects + * of the configuration, such as target formatting, document handling, + * representation depth, and scope of operation. */ struct KwArgs { bool no_target_format = false; @@ -58,10 +61,10 @@ struct KwArgs { /** * @brief Abstract base class for the AtomDB database interface. * - * The AtomDB class defines the interface for interacting with the AtomDB database. - * It provides various pure virtual methods for querying, adding, and managing atoms, - * nodes, and links within the database. Derived classes must implement these methods - * to provide concrete functionality. + * The AtomDB class defines the interface for interacting with the AtomDB + * database. It provides various pure virtual methods for querying, adding, and + * managing atoms, nodes, and links within the database. Derived classes must + * implement these methods to provide concrete functionality. * * The AtomDB interface supports operations such as: * - Retrieving atoms by various criteria (e.g., field, index, text field). @@ -115,33 +118,38 @@ class AtomDB { * @brief Checks if a node with the specified type and name exists. * @param node_type A string representing the type of the node. * @param node_name A string representing the name of the node. - * @return A boolean value indicating whether the node exists (true) or not (false). + * @return A boolean value indicating whether the node exists (true) or not + * (false). */ bool node_exists(const string& node_type, const string& node_name) const; /** * @brief Checks if a link with the specified type and target handles exists. * @param link_type A string representing the type of the link. - * @param target_handles A vector of strings representing the handles of the link's targets. - * @return A boolean value indicating whether the link exists (true) or not (false). + * @param target_handles A vector of strings representing the handles of the + * link's targets. + * @return A boolean value indicating whether the link exists (true) or not + * (false). */ bool link_exists(const string& link_type, const StringList& target_handles) const; /** - * @brief Retrieves an atom from the database using its handle and optional params. + * @brief Retrieves an atom from the database using its handle and optional + * params. * @param handle A string representing the handle of the atom to be retrieved. - * @param kwargs An optional Kwargs object containing additional retrieval options, as follows: - * `no_target_format` (`bool`, optional): If True, return the document without - * transforming it to the target format. Defaults to False. - * `targets_document` (`bool`, optional): If True, include the `targets_document` - * in the response. Defaults to False. - * `deep_representation` (`bool`, optional): If True, include a deep - * representation of the targets. Defaults to False. + * @param kwargs An optional Kwargs object containing additional retrieval + * options, as follows: `no_target_format` (`bool`, optional): If True, return + * the document without transforming it to the target format. Defaults to + * False. `targets_document` (`bool`, optional): If True, include the + * `targets_document` in the response. Defaults to False. + * `deep_representation` (`bool`, optional): If True, include a + * deep representation of the targets. Defaults to False. * @return A const shared pointer to an Atom object. */ const shared_ptr get_atom(const string& handle, const KwArgs& kwargs = {}) const; - // PURE VIRTUAL PUBLIC METHODS ///////////////////////////////////////////////////////////////// + // PURE VIRTUAL PUBLIC METHODS + // ///////////////////////////////////////////////////////////////// /** * @brief Get the handle of the node with the specified type and name. @@ -166,7 +174,8 @@ class AtomDB { virtual const string get_node_type(const string& node_handle) const = 0; /** - * @brief Get the handles of (a) node(s) of the specified type containing the given substring. + * @brief Get the handles of (a) node(s) of the specified type containing the + * given substring. * @param node_type The node type. * @param substring The substring to search for in node names. * @return List of handles of nodes whose names matched the criteria. @@ -184,13 +193,16 @@ class AtomDB { /** * @brief Retrieves atoms from the database using the specified index. - * @param index_id The ID of the index to use for retrieving atoms from the database. + * @param index_id The ID of the index to use for retrieving atoms from the + * database. * @param query A vector of ordered maps representing the query parameters. - * @param cursor An integer representing the cursor position for pagination (default is 0). - * @param chunk_size An integer representing the number of atoms to retrieve in one chunk - * (default is 500). - * @return A pair containing an cursor and a list of atoms. The cursor is used for pagination - * or further retrieval operations, and the list contains the retrieved atoms. + * @param cursor An integer representing the cursor position for pagination + * (default is 0). + * @param chunk_size An integer representing the number of atoms to retrieve + * in one chunk (default is 500). + * @return A pair containing an cursor and a list of atoms. The cursor is used + * for pagination or further retrieval operations, and the list contains the + * retrieved atoms. */ virtual const pair get_atoms_by_index( const string& index_id, @@ -266,7 +278,8 @@ class AtomDB { /** * @brief Retrieves incoming link handles for the specified atom. * @param atom_handle A string representing the handle of the atom. - * @param kwargs An const reference to a Kwargs object containing additional retrieval options. + * @param kwargs An const reference to a Kwargs object containing additional + * retrieval options. * @return A list of strings representing the incoming link handles. */ virtual const StringList get_incoming_links_handles(const string& atom_handle, @@ -275,7 +288,8 @@ class AtomDB { /** * @brief Retrieves incoming link atoms for the specified atom. * @param atom_handle A string representing the handle of the atom. - * @param kwargs An const reference to a Kwargs object containing additional retrieval options. + * @param kwargs An const reference to a Kwargs object containing additional + * retrieval options. * @return A list of Atom objects representing the incoming links. */ virtual const vector> get_incoming_links_atoms( @@ -285,7 +299,8 @@ class AtomDB { * @brief Retrieves matched links of the specified type and target handles. * @param link_type A string representing the type of the links to retrieve. * @param target_handles A list of strings representing the target handles. - * @param kwargs An const reference to a Kwargs object containing additional retrieval options. + * @param kwargs An const reference to a Kwargs object containing additional + * retrieval options. * @return A set of handles that matched. */ virtual const StringUnorderedSet get_matched_links(const string& link_type, @@ -295,7 +310,8 @@ class AtomDB { /** * @brief Retrieves matched type templates based on the specified template. * @param _template A list of strings representing the template. - * @param kwargs An const reference to a Kwargs object containing additional retrieval options. + * @param kwargs An const reference to a Kwargs object containing additional + * retrieval options. * @return A set of handles that matched. */ virtual const StringUnorderedSet get_matched_type_template(const StringList& _template, @@ -304,7 +320,8 @@ class AtomDB { /** * @brief Retrieves matched types based on the specified link type. * @param link_type A string representing the type of the links to retrieve. - * @param kwargs A const reference to a Kwargs object containing additional retrieval options. + * @param kwargs A const reference to a Kwargs object containing additional + * retrieval options. * @return A set of handles that matched. */ virtual const StringUnorderedSet get_matched_type(const string& link_type, @@ -313,13 +330,15 @@ class AtomDB { /** * @brief Retrieves the type of the atom with the specified handle. * @param handle A string representing the handle of the atom. - * @return An optional string containing the type of the atom if found, otherwise nullopt. + * @return An optional string containing the type of the atom if found, + * otherwise nullopt. */ virtual const optional get_atom_type(const string& handle) const = 0; /** * @brief Count the total number of atoms in the database. - * @return A dictionary containing the count of node atoms, link atoms, and total atoms. + * @return A dictionary containing the count of node atoms, link atoms, and + * total atoms. */ virtual const unordered_map count_atoms() const = 0; @@ -330,37 +349,44 @@ class AtomDB { /** * @brief Adds a node to the database. - * @param node_params A NodeParams object containing the parameters for the node. + * @param node_params A NodeParams object containing the parameters for the + * node. * @return A const shared pointer to a Node object. */ virtual const shared_ptr add_node(const Node& node_params) = 0; /** * @brief Adds a link to the database. - * @param link_params A LinkParams object containing the parameters for the link. - * @param toplevel A boolean indicating whether the link is a top-level link (default is true). + * @param link_params A LinkParams object containing the parameters for the + * link. + * @param toplevel A boolean indicating whether the link is a top-level link + * (default is true). * @return A const shared pointer to a Link object. */ virtual const shared_ptr add_link(const Link& link_params, bool toplevel = true) = 0; /** - * @brief Reindexes the inverted pattern index according to the passed templates. + * @brief Reindexes the inverted pattern index according to the passed + * templates. * - * This function reindexes the inverted pattern index based on the specified pattern - * templates. The pattern templates are specified by atom type in a map, where each - * atom type maps to a pattern template. + * This function reindexes the inverted pattern index based on the specified + * pattern templates. The pattern templates are specified by atom type in a + * map, where each atom type maps to a pattern template. * - * @param pattern_index_templates A map where the keys are atom types and the values - * are pattern templates. Each pattern template is a vector of maps, where each - * map specifies a pattern template with: - * - "named_type": A boolean indicating whether the named type should be included. - * - "selected_positions": A vector of integers specifying the selected positions. + * @param pattern_index_templates A map where the keys are atom types and the + * values are pattern templates. Each pattern template is a vector of maps, + * where each map specifies a pattern template with: + * - "named_type": A boolean indicating whether the named type should + * be included. + * - "selected_positions": A vector of integers specifying the selected + * positions. * - * Pattern templates are applied to each link entered in the atom space to determine - * which entries should be created in the inverted pattern index. Entries in the inverted - * pattern index are like patterns where the link type and each of its targets may be - * replaced by wildcards. For instance, given a similarity link Similarity(handle1, handle2), - * it could be used to create any of the following entries in the inverted pattern index: + * Pattern templates are applied to each link entered in the atom space to + * determine which entries should be created in the inverted pattern index. + * Entries in the inverted pattern index are like patterns where the link type + * and each of its targets may be replaced by wildcards. For instance, given a + * similarity link Similarity(handle1, handle2), it could be used to create + * any of the following entries in the inverted pattern index: * * - *(handle1, handle2) * @@ -370,10 +396,10 @@ class AtomDB { * * - Similarity(*, *) * - * If we create all possibilities of index entries for all links, the pattern index size - * will grow exponentially, so we limit the entries we want to create by each type of link. - * This is what a pattern template for a given link type is. For instance, if we apply this - * pattern template: + * If we create all possibilities of index entries for all links, the pattern + * index size will grow exponentially, so we limit the entries we want to + * create by each type of link. This is what a pattern template for a given + * link type is. For instance, if we apply this pattern template: * * @code * `{ "named_type": false, "selected_positions": {0, 1} }` @@ -425,7 +451,8 @@ class AtomDB { /** * @brief Insert multiple documents into the database. - * @param documents A list of Atom objects, each representing a document to be inserted into the db. + * @param documents A list of Atom objects, each representing a document to be + * inserted into the db. */ virtual void bulk_insert(const vector>& documents) = 0; @@ -443,26 +470,32 @@ class AtomDB { /** * @brief Reformats a document based on the provided params. * @param document A shared pointer to the Atom object to be reformatted. - * @param kwargs A const reference to a Kwargs object containing the reformatting options. - * @return A shared pointer with a copy of the reference object but with the new format. + * @param kwargs A const reference to a Kwargs object containing the + * reformatting options. + * @return A shared pointer with a copy of the reference object but with the + * new format. */ const shared_ptr _reformat_document(const shared_ptr& document, const KwArgs& kwargs = {}) const; protected: - // PROTECTED METHODS /////////////////////////////////////////////////////////////////////////// + // PROTECTED METHODS + // /////////////////////////////////////////////////////////////////////////// /** * @brief Builds a node with the specified parameters. - * @param node_params A NodeParams object containing the parameters for the node. + * @param node_params A NodeParams object containing the parameters for the + * node. * @return A shared pointer to a Node object. */ shared_ptr _build_node(const Node& node_params); /** * @brief Builds a link with the specified parameters. - * @param link_params A LinkParams object containing the parameters for the link. - * @param is_toplevel A boolean indicating whether the link is a top-level link. + * @param link_params A LinkParams object containing the parameters for the + * link. + * @param is_toplevel A boolean indicating whether the link is a top-level + * link. * @return A shared pointer to a Link object. */ virtual shared_ptr _build_link(const Link& link_params, bool is_toplevel = true); @@ -470,7 +503,8 @@ class AtomDB { /** * @brief Retrieves an atom from the database using its handle. * @param handle A string representing the handle of the atom to be retrieved. - * @return A const shared pointer to the Atom object representing the retrieved atom. + * @return A const shared pointer to the Atom object representing the + * retrieved atom. */ virtual const shared_ptr _get_atom(const string& handle) const = 0; }; diff --git a/src/hyperon_das_atomdb_cpp_lib/document_types.h b/src/hyperon_das_atomdb_cpp_lib/document_types.h index c4cbbff..1e5feb5 100644 --- a/src/hyperon_das_atomdb_cpp_lib/document_types.h +++ b/src/hyperon_das_atomdb_cpp_lib/document_types.h @@ -1,17 +1,20 @@ /** * @file document_types.h - * @brief Defines various classes representing atomic entities and their relationships in the atom - * database. + * @brief Defines various classes representing atomic entities and their + * relationships in the atom database. * - * This header file contains the definitions of several classes that represent different types of - * atomic entities and their relationships within the atom database. The classes include: - * - CustomAttributes: A type alias for `std::unordered_map`. - * - Atom: Represents a basic atomic entity with attributes such as ID, handle, composite type hash, - * named type, and optional custom attributes. - * - Node: Represents a node in the atom database, extending the Atom class by adding a name - * attribute. - * - Link: Represents a link in the atom database, encapsulating a composite type, named type hash, - * and a list of target hashes. It supports nested composite types and validates their structure. + * This header file contains the definitions of several classes that represent + * different types of atomic entities and their relationships within the atom + * database. The classes include: + * - CustomAttributes: A type alias for `std::unordered_map`. + * - Atom: Represents a basic atomic entity with attributes such as ID, handle, + * composite type hash, named type, and optional custom attributes. + * - Node: Represents a node in the atom database, extending the Atom class by + * adding a name attribute. + * - Link: Represents a link in the atom database, encapsulating a composite + * type, named type hash, and a list of target hashes. It supports nested + * composite types and validates their structure. */ #pragma once @@ -78,10 +81,10 @@ static string custom_attributes_to_string(const CustomAttributes& custom_attribu * @class Atom * @brief Represents an atomic entity with various attributes. * - * The Atom class encapsulates the properties of an atomic entity, including its ID, handle, - * composite type hash, named type, and optional custom attributes. It provides constructors - * for initialization, comparison operators, and a method to convert the object to a string - * representation. + * The Atom class encapsulates the properties of an atomic entity, including its + * ID, handle, composite type hash, named type, and optional custom attributes. + * It provides constructors for initialization, comparison operators, and a + * method to convert the object to a string representation. */ class Atom { public: @@ -96,10 +99,11 @@ class Atom { /** * @brief Constructs an Atom with a named type and optional custom attributes. * @param named_type The named type of the Atom. - * @param custom_attributes Optional custom attributes for the Atom. Defaults to an empty map. - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Atom objects, use the - * constructor with all parameters. + * @param custom_attributes Optional custom attributes for the Atom. Defaults + * to an empty map. + * @note This constructor is intended to be used only when passing in the + * basic building parameters to other functions. For creating complete new + * Atom objects, use the constructor with all parameters. */ Atom(const string& named_type, const CustomAttributes& custom_attributes = CustomAttributes{}) : named_type(named_type), custom_attributes(custom_attributes) {} @@ -108,9 +112,11 @@ class Atom { * @brief Constructs an Atom object with the given parameters. * @param id The unique identifier for the atom. * @param handle The handle for the atom. - * @param composite_type_hash The hash representing the composite type of the atom. + * @param composite_type_hash The hash representing the composite type of the + * atom. * @param named_type The named type of the atom. - * @param custom_attributes Optional custom attributes for the atom. Defaults to an empty map. + * @param custom_attributes Optional custom attributes for the atom. Defaults + * to an empty map. */ Atom(const string& id, const string& handle, @@ -146,8 +152,8 @@ class Atom { /** * @brief Converts the object to a string representation. - * @return A string representing the object, including its ID, handle, composite type hash, - * named type, and custom attributes. + * @return A string representing the object, including its ID, handle, + * composite type hash, named type, and custom attributes. */ virtual const string to_string() const noexcept { string result = "_id: '" + this->_id + "'"; @@ -164,8 +170,9 @@ class Atom { * @class Node * @brief Represents a node in the atom database, inheriting from Atom. * - * The Node class extends the Atom class by adding a name attribute. It includes constructors, - * equality operators, and a string representation method. The name attribute must not be empty. + * The Node class extends the Atom class by adding a name attribute. It includes + * constructors, equality operators, and a string representation method. The + * name attribute must not be empty. */ class Node : public Atom { public: @@ -177,10 +184,11 @@ class Node : public Atom { * @brief Constructs a Node with a type, name, and optional custom attributes. * @param type The type of the Node. * @param name The name of the Node. - * @param custom_attributes Optional custom attributes for the Node. Defaults to an empty map. - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Node objects, use the - * constructor with all parameters. + * @param custom_attributes Optional custom attributes for the Node. Defaults + * to an empty map. + * @note This constructor is intended to be used only when passing in the + * basic building parameters to other functions. For creating complete new + * Node objects, use the constructor with all parameters. * * Usage: * ``` @@ -190,12 +198,14 @@ class Node : public Atom { * Node( * "Concept", // type * "human", // name - * { {"weight": 0.8}, {"immutable": false} } // custom_attributes (optional) + * { {"weight": 0.8}, {"immutable": false} } // custom_attributes + * (optional) * ) * ); * * bool node2_is_immutable = ( - * get_custom_attribute(node2->custom_attributes, "immutable").value_or(false) + * get_custom_attribute(node2->custom_attributes, + * "immutable").value_or(false) * ); * cout << node2_is_immutable << endl; * // Output: @@ -203,9 +213,10 @@ class Node : public Atom { * * cout << node2.to_string() << endl; * // Output: - * Node(_id: 'af12f10f9ae2002a1607ba0b47ba8407', handle: 'af12f10f9ae2002a1607ba0b47ba8407', - * composite_type_hash: 'd99a604c79ce3c2e76a2f43488d5d4c3', named_type: 'Concept', custom_attributes: - * {immutable: false, weight: 0.800000}, name: 'human') + * Node(_id: 'af12f10f9ae2002a1607ba0b47ba8407', handle: + * 'af12f10f9ae2002a1607ba0b47ba8407', composite_type_hash: + * 'd99a604c79ce3c2e76a2f43488d5d4c3', named_type: 'Concept', + * custom_attributes: {immutable: false, weight: 0.800000}, name: 'human') * ``` */ Node(const string& type, @@ -220,7 +231,8 @@ class Node : public Atom { * @param composite_type_hash The hash representing the composite type. * @param named_type The named type of the Node. * @param name The name of the Node. - * @param custom_attributes Optional custom attributes for the Node. Defaults to an empty map. + * @param custom_attributes Optional custom attributes for the Node. Defaults + * to an empty map. */ Node(const string& id, const string& handle, @@ -256,18 +268,20 @@ class Node : public Atom { * @class Link * @brief Represents a link in the atom database, inheriting from Atom. * - * The Link class encapsulates a composite type, a named type hash, and a list of target hashes. - * It supports nested composite types and validates their structure. The class also provides - * functionality to compare links, convert them to string representations, and manage target - * documents. + * The Link class encapsulates a composite type, a named type hash, and a list + * of target hashes. It supports nested composite types and validates their + * structure. The class also provides functionality to compare links, convert + * them to string representations, and manage target documents. */ class Link : public Atom { public: using TargetsDocuments = vector>; /** - * `composite_type` is designed to hold a list of elements, where each element can either be a - * `string` (single hash) or another list of `strings`, allowing multiple levels of nesting. + * `composite_type` is designed to hold a list of elements, where each element + can either be a + * `string` (single hash) or another list of `strings`, allowing multiple + levels of nesting. * Example: ``` [ @@ -294,13 +308,15 @@ class Link : public Atom { Link() = default; /** - * @brief Constructs a Link with a type, targets documents, and optional custom attributes. + * @brief Constructs a Link with a type, targets documents, and optional + * custom attributes. * @param type The type of the Link. * @param targets The targets documents associated with the Link. - * @param custom_attributes Optional custom attributes for the Link. Defaults to an empty map. - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Link objects, use the - * constructor with all parameters. + * @param custom_attributes Optional custom attributes for the Link. Defaults + * to an empty map. + * @note This constructor is intended to be used only when passing in the + * basic building parameters to other functions. For creating complete new + * Link objects, use the constructor with all parameters. * * Usage: * ``` @@ -308,24 +324,24 @@ class Link : public Atom { * auto link = db.add_link( * Link( * "Similarity", // type - * { // targets of Similarity link - * {Node("Concept", "monkey")}, // a node as a target of Similarity link - * {Node("Concept", "human")}, // another node as a target - * { // a link as a target of Similarity link - * Link("Dummicity", // type - * { // targets of Dummicity link - * {Node("Concept", "dummy1")}, - * {Node("Concept", "dummy2")} + * { // targets of + * Similarity link {Node("Concept", "monkey")}, // a node as a + * target of Similarity link {Node("Concept", "human")}, // + * another node as a target { // a + * link as a target of Similarity link Link("Dummicity", // type { // targets + * of Dummicity link {Node("Concept", "dummy1")}, {Node("Concept", "dummy2")} * } * ) * } * }, - * { {"weight": 0.8}, {"immutable": false} } // custom_attributes (optional) + * { {"weight": 0.8}, {"immutable": false} } // custom_attributes + * (optional) * ) * ); * * double link_weight = ( - * get_custom_attribute(link->custom_attributes, "weight").value_or(0.0) + * get_custom_attribute(link->custom_attributes, + * "weight").value_or(0.0) * ); * cout << link_weight << endl; * // Output: @@ -333,15 +349,17 @@ class Link : public Atom { * * cout << link.to_string() << endl; * // Output: - * Link(_id: '8ef9c2093150a022204fa6c9f0bc94f8', handle: '8ef9c2093150a022204fa6c9f0bc94f8', - * composite_type_hash: '8dd4c9ab591dbbd1e6eb511e71ef5aa9', named_type: 'Similarity', + * Link(_id: '8ef9c2093150a022204fa6c9f0bc94f8', handle: + * '8ef9c2093150a022204fa6c9f0bc94f8', composite_type_hash: + * '8dd4c9ab591dbbd1e6eb511e71ef5aa9', named_type: 'Similarity', * custom_attributes: {immutable: false, weight: 0.800000}, composite_type: * ['a9dea78180588431ec64d6bc4872fdbc', 'd99a604c79ce3c2e76a2f43488d5d4c3', * 'd99a604c79ce3c2e76a2f43488d5d4c3', ['44d25cf84a95f144d6e603ca28caadba', - * 'd99a604c79ce3c2e76a2f43488d5d4c3', 'd99a604c79ce3c2e76a2f43488d5d4c3']], named_type_hash: - * 'a9dea78180588431ec64d6bc4872fdbc', targets: ['1cdffc6b0b89ff41d68bec237481d1e1', - * 'af12f10f9ae2002a1607ba0b47ba8407', '087091095a266df1bfcc1ee01e79811c'], is_toplevel: true, - * targets_documents: []) + * 'd99a604c79ce3c2e76a2f43488d5d4c3', 'd99a604c79ce3c2e76a2f43488d5d4c3']], + * named_type_hash: 'a9dea78180588431ec64d6bc4872fdbc', targets: + * ['1cdffc6b0b89ff41d68bec237481d1e1', 'af12f10f9ae2002a1607ba0b47ba8407', + * '087091095a266df1bfcc1ee01e79811c'], is_toplevel: true, targets_documents: + * []) * ``` */ Link(const string& type, @@ -359,8 +377,10 @@ class Link : public Atom { * @param named_type_hash The hash of the named type. * @param targets The vector of target strings. * @param is_toplevel Boolean indicating if the link is top-level. - * @param custom_attributes Optional custom attributes. Defaults to an empty map. - * @param targets_documents Optional targets documents. Defaults to an empty vector. + * @param custom_attributes Optional custom attributes. Defaults to an empty + * map. + * @param targets_documents Optional targets documents. Defaults to an empty + * vector. */ Link(const string& id, const string& handle, @@ -390,7 +410,8 @@ class Link : public Atom { } if (not this->validate_composite_type(this->composite_type)) { throw invalid_argument( - "Invalid composite type. All elements must be strings or lists of strings."); + "Invalid composite type. All elements must be " + "strings or lists of strings."); } if (this->named_type_hash.empty()) { throw invalid_argument("Named type hash cannot be empty."); @@ -402,8 +423,8 @@ class Link : public Atom { /** * @brief Converts the Link object to a string representation. - * @return A string representing the Link object, including its composite type, named type hash, - * targets, top-level status, and target documents. + * @return A string representing the Link object, including its composite + * type, named type hash, targets, top-level status, and target documents. */ const string to_string() const noexcept override { string result = "Link(" + Atom::to_string(); @@ -463,13 +484,13 @@ class Link : public Atom { /** * @brief Validates the structure of a composite type. * - * This function checks whether the given composite type adheres to the expected structure. - * A composite type is a list where each element can be either a string or another list of - * the same type. The function ensures that all elements in the composite type meet these - * criteria. + * This function checks whether the given composite type adheres to the + * expected structure. A composite type is a list where each element can be + * either a string or another list of the same type. The function ensures that + * all elements in the composite type meet these criteria. * - * @param composite_type A list of elements of type std::any representing the composite type - * to be validated. + * @param composite_type A list of elements of type std::any representing the + * composite type to be validated. * @return true if the composite type is valid, false otherwise. */ static bool validate_composite_type(const ListOfAny& composite_type) { diff --git a/src/hyperon_das_atomdb_cpp_lib/exceptions.h b/src/hyperon_das_atomdb_cpp_lib/exceptions.h index 102d121..ee1110b 100644 --- a/src/hyperon_das_atomdb_cpp_lib/exceptions.h +++ b/src/hyperon_das_atomdb_cpp_lib/exceptions.h @@ -1,29 +1,34 @@ /** * @file exceptions.h - * @brief Defines custom exception classes for the Atom Database (atomdb) library. + * @brief Defines custom exception classes for the Atom Database (atomdb) + * library. * - * This header file contains the definitions of various exception classes used in the Atom - * Database (atomdb) library. These exceptions are designed to handle specific error conditions - * that may arise during the operation of the database. Each exception class inherits from - * AtomDbBaseException, which in turn inherits from the standard std::exception class. + * This header file contains the definitions of various exception classes used + * in the Atom Database (atomdb) library. These exceptions are designed to + * handle specific error conditions that may arise during the operation of the + * database. Each exception class inherits from AtomDbBaseException, which in + * turn inherits from the standard std::exception class. * - * The AtomDbBaseException class provides a mechanism to store and retrieve detailed error - * messages. It uses a static buffer (`what_buffer`) to ensure that the exception message remains - * valid and accessible even after the original C-string has been invalidated. This is - * particularly useful when interfacing with libraries like `nanobind` that may lazily access + * The AtomDbBaseException class provides a mechanism to store and retrieve + * detailed error messages. It uses a static buffer (`what_buffer`) to ensure + * that the exception message remains valid and accessible even after the + * original C-string has been invalidated. This is particularly useful when + * interfacing with libraries like `nanobind` that may lazily access * std::exception::what(). * * The following custom exception classes are defined: * - AtomDoesNotExist: Thrown when an atom does not exist in the database. * - AddNodeException: Thrown when adding a node to the database fails. * - AddLinkException: Thrown when adding a link to the database fails. - * - InvalidOperationException: Thrown when an invalid operation is performed on the database. + * - InvalidOperationException: Thrown when an invalid operation is performed on + * the database. * - RetryException: Raised for retryable errors. * - InvalidAtomDB: Raised for invalid Atom DB operations. * - * Each of these exception classes inherits from AtomDbBaseException and can be used to provide - * detailed error messages specific to the context in which the error occurred. + * Each of these exception classes inherits from AtomDbBaseException and can be + * used to provide detailed error messages specific to the context in which the + * error occurred. */ #pragma once @@ -38,11 +43,11 @@ namespace atomdb { /** * @brief Buffer to store the exception message. - * nanobind makes a lazy access to std::exception::what(), which can result in the - * underlying C-string being lost or invalidated. To work around this issue, we - * create a static buffer (what_buffer) to store the exception message. This ensures - * that the message remains valid and accessible even after the original C-string - * has been invalidated. + * nanobind makes a lazy access to std::exception::what(), which can result in + * the underlying C-string being lost or invalidated. To work around this issue, + * we create a static buffer (what_buffer) to store the exception message. This + * ensures that the message remains valid and accessible even after the original + * C-string has been invalidated. */ static char what_buffer[BUFFER_SIZE]; @@ -84,7 +89,8 @@ class AddLinkException : public AtomDbBaseException { }; /** - * @brief Exception thrown when an invalid operation is performed on the database. + * @brief Exception thrown when an invalid operation is performed on the + * database. */ class InvalidOperationException : public AtomDbBaseException { using AtomDbBaseException::AtomDbBaseException; diff --git a/src/hyperon_das_atomdb_cpp_lib/expression_hasher.h b/src/hyperon_das_atomdb_cpp_lib/expression_hasher.h index 123ca01..7167765 100644 --- a/src/hyperon_das_atomdb_cpp_lib/expression_hasher.h +++ b/src/hyperon_das_atomdb_cpp_lib/expression_hasher.h @@ -1,22 +1,25 @@ /** * @file expression_hasher.h - * @brief Header file for the ExpressionHasher class, providing utilities for generating MD5 hashes - * for various types of expressions. + * @brief Header file for the ExpressionHasher class, providing utilities for + * generating MD5 hashes for various types of expressions. * - * This file contains the definition of the ExpressionHasher class, which offers static methods to - * compute MD5 hashes for different types of expressions, including named types, terminal expressions, - * composite expressions, and general expressions. The class leverages the mbedtls library for MD5 - * hashing operations. + * This file contains the definition of the ExpressionHasher class, which offers + * static methods to compute MD5 hashes for different types of expressions, + * including named types, terminal expressions, composite expressions, and + * general expressions. The class leverages the mbedtls library for MD5 hashing + * operations. * - * The ExpressionHasher class is designed to handle strings and lists of strings as input for hashing. - * It ensures that the generated hashes are consistent and unique for different expressions, making it - * useful for scenarios where expression uniqueness and integrity are critical. + * The ExpressionHasher class is designed to handle strings and lists of strings + * as input for hashing. It ensures that the generated hashes are consistent and + * unique for different expressions, making it useful for scenarios where + * expression uniqueness and integrity are critical. * - * @note The class uses a maximum hashable string size of 100,000 characters and a joining character - * of a single space (' ') for concatenating elements before hashing. + * @note The class uses a maximum hashable string size of 100,000 characters and + * a joining character of a single space (' ') for concatenating elements before + * hashing. * - * @remark The class throws exceptions in cases where hashing operations fail or input constraints - * are violated, ensuring robust error handling. + * @remark The class throws exceptions in cases where hashing operations fail or + * input constraints are violated, ensuring robust error handling. * * Dependencies: * - mbedtls/md5.h: For MD5 hashing functions. @@ -38,17 +41,20 @@ namespace atomdb { /** * @class ExpressionHasher - * @brief A utility class for generating various types of hashes for expressions. + * @brief A utility class for generating various types of hashes for + * expressions. * - * The ExpressionHasher class provides static methods to compute MD5 hashes for different types of - * expressions, including named types, terminal expressions, composite expressions, and general - * expressions. It uses the mbedtls library for MD5 hashing. + * The ExpressionHasher class provides static methods to compute MD5 hashes for + * different types of expressions, including named types, terminal expressions, + * composite expressions, and general expressions. It uses the mbedtls library + * for MD5 hashing. * - * @note This class is designed to handle strings and lists of strings as input for hashing. + * @note This class is designed to handle strings and lists of strings as input + * for hashing. * - * @remark The class ensures that the generated hashes are consistent and unique for different - * expressions, making it useful for scenarios where expression uniqueness and integrity - * are critical. + * @remark The class ensures that the generated hashes are consistent and unique + * for different expressions, making it useful for scenarios where expression + * uniqueness and integrity are critical. */ class ExpressionHasher { public: @@ -81,7 +87,8 @@ class ExpressionHasher { /** * @brief Generates a hash for a composite expression. * - * @param elements A vector of strings representing the elements of the composite expression. + * @param elements A vector of strings representing the elements of the + * composite expression. * @return A string representing the hash of the composite expression. */ static const string composite_hash(const StringList& elements); @@ -93,7 +100,8 @@ class ExpressionHasher { * by applying additional hashing logic. * * @param hash_base A string representing the base hash. - * @return A string representing the composite hash generated from the base hash. + * @return A string representing the composite hash generated from the base + * hash. */ static const string composite_hash(const string& hash_base); @@ -101,7 +109,8 @@ class ExpressionHasher { * @brief Generates a hash for an expression. * * @param type_hash The hash of the type of the expression. - * @param elements A vector of strings representing the elements of the expression. + * @param elements A vector of strings representing the elements of the + * expression. * @return A string representing the hash of the expression. */ static const string expression_hash(const string& type_hash, const StringList& elements); diff --git a/src/hyperon_das_atomdb_cpp_lib/patterns.h b/src/hyperon_das_atomdb_cpp_lib/patterns.h index cb79995..4965fc4 100644 --- a/src/hyperon_das_atomdb_cpp_lib/patterns.h +++ b/src/hyperon_das_atomdb_cpp_lib/patterns.h @@ -1,15 +1,18 @@ /** * @file patterns.h - * @brief Utility functions for generating and manipulating binary matrices and pattern keys. + * @brief Utility functions for generating and manipulating binary matrices and + * pattern keys. * - * This header file contains utility functions for generating binary matrices, multiplying - * binary matrices by string matrices, and building pattern keys from a list of hash strings. - * These functions are part of the atomdb namespace and are used for various operations - * involving pattern generation and manipulation in the context of the das-atom-db project. + * This header file contains utility functions for generating binary matrices, + * multiplying binary matrices by string matrices, and building pattern keys + * from a list of hash strings. These functions are part of the atomdb namespace + * and are used for various operations involving pattern generation and + * manipulation in the context of the das-atom-db project. * * The main functionalities provided by this module include: * - Generating a binary matrix of a specified size. - * - Multiplying a binary matrix by a string matrix to produce a resulting matrix. + * - Multiplying a binary matrix by a string matrix to produce a resulting + * matrix. * - Building pattern keys using a list of hash strings. */ #pragma once @@ -47,7 +50,8 @@ unordered_map BINARY_MATRIX_CACHE = {{0, {{}}}}; * * @param numbers The size of the binary matrix to generate. * If numbers equal to 0, returns a matrix with an empty vector. - * @return A const reference to a binary matrix represented as a vector of vectors. + * @return A const reference to a binary matrix represented as a vector of + * vectors. */ const IntMatrix& generate_binary_matrix(size_t numbers) { if (BINARY_MATRIX_CACHE.find(numbers) == BINARY_MATRIX_CACHE.end()) { @@ -72,9 +76,11 @@ const IntMatrix& generate_binary_matrix(size_t numbers) { * * This function takes a binary matrix and a string matrix, and multiplies them * to produce a resulting matrix. Each element in the binary matrix determines - * whether to include the corresponding string from the string matrix or a wildcard. + * whether to include the corresponding string from the string matrix or a + * wildcard. * - * @param binary_matrix A binary matrix represented as a vector of vectors of integers. + * @param binary_matrix A binary matrix represented as a vector of vectors of + * integers. * @param string_matrix A vector of strings to multiply with the binary matrix. * @return A matrix represented as a vector of vectors of strings, where each * subvector is a row in the resulting matrix. @@ -103,7 +109,8 @@ StringMatrix multiply_binary_matrix_by_string_matrix(const IntMatrix& binary_mat * @brief Builds pattern keys using a list of hashes. * * This function takes a list of hash strings, generates a binary matrix, - * multiplies it by the hash list, and then generates pattern keys from the result. + * multiplies it by the hash list, and then generates pattern keys from the + * result. * * @param hash_list A vector of hash strings to build pattern keys from. * @return A vector of pattern keys generated from the hash list. diff --git a/src/hyperon_das_atomdb_cpp_lib/ram_only.cc b/src/hyperon_das_atomdb_cpp_lib/ram_only.cc index 5d8510a..c29a381 100644 --- a/src/hyperon_das_atomdb_cpp_lib/ram_only.cc +++ b/src/hyperon_das_atomdb_cpp_lib/ram_only.cc @@ -9,7 +9,8 @@ using namespace std; using namespace atomdb; -// PUBLIC METHODS ////////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS +// ////////////////////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------------ const string InMemoryDB::get_node_handle(const string& node_type, const string& node_name) const { @@ -356,7 +357,8 @@ void InMemoryDB::commit(const optional>& buffer) { throw runtime_error("Not implemented"); } -// PROTECTED OR PRIVATE METHODS //////////////////////////////////////////////////////////////////// +// PROTECTED OR PRIVATE METHODS +// //////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------------ const shared_ptr InMemoryDB::_get_atom(const string& handle) const { diff --git a/src/hyperon_das_atomdb_cpp_lib/ram_only.h b/src/hyperon_das_atomdb_cpp_lib/ram_only.h index 1b765a4..2c83285 100644 --- a/src/hyperon_das_atomdb_cpp_lib/ram_only.h +++ b/src/hyperon_das_atomdb_cpp_lib/ram_only.h @@ -1,23 +1,26 @@ /** * @file ram_only.h - * @brief Defines in-memory database classes for managing atoms, nodes, and links. + * @brief Defines in-memory database classes for managing atoms, nodes, and + * links. * - * This header file contains the definitions for the `Database` and `InMemoryDB` classes, - * which provide in-memory storage and management of various data types, including atoms, - * nodes, and links. These classes are designed to facilitate efficient in-memory operations - * without the overhead of persistent storage, making them suitable for applications that - * require fast data access and manipulation. + * This header file contains the definitions for the `Database` and `InMemoryDB` + * classes, which provide in-memory storage and management of various data + * types, including atoms, nodes, and links. These classes are designed to + * facilitate efficient in-memory operations without the overhead of persistent + * storage, making them suitable for applications that require fast data access + * and manipulation. * - * The `Database` class serves as a container for different types of data, using unordered - * maps to store atom types, nodes, links, and sets for managing relationships between them. - * It provides basic functionalities such as initialization and cleanup of the stored data. + * The `Database` class serves as a container for different types of data, using + * unordered maps to store atom types, nodes, links, and sets for managing + * relationships between them. It provides basic functionalities such as + * initialization and cleanup of the stored data. * - * The `InMemoryDB` class extends the `AtomDB` class and offers a comprehensive set of - * methods for adding, retrieving, and managing atoms, nodes, links, and their relationships. - * It includes functionalities for querying data, managing indexes, and handling complex - * data structures in memory. This class is intended for use in scenarios where data does - * not need to be persisted across sessions or can be reconstructed from other sources if - * needed. + * The `InMemoryDB` class extends the `AtomDB` class and offers a comprehensive + * set of methods for adding, retrieving, and managing atoms, nodes, links, and + * their relationships. It includes functionalities for querying data, managing + * indexes, and handling complex data structures in memory. This class is + * intended for use in scenarios where data does not need to be persisted across + * sessions or can be reconstructed from other sources if needed. * * Key functionalities provided by the `InMemoryDB` class include: * - Adding and retrieving nodes and links. @@ -28,9 +31,9 @@ * - Bulk insertion and retrieval of atoms. * - Committing changes to the database. * - * The classes in this module are designed to be flexible and efficient, providing a robust - * solution for managing in-memory data structures in applications that require high - * performance and low latency. + * The classes in this module are designed to be flexible and efficient, + * providing a robust solution for managing in-memory data structures in + * applications that require high performance and low latency. */ #pragma once @@ -43,7 +46,8 @@ using namespace std; namespace atomdb { /** - * @brief Represents an in-memory database for storing and managing atoms, nodes, and links. + * @brief Represents an in-memory database for storing and managing atoms, + * nodes, and links. */ class Database { public: @@ -67,26 +71,29 @@ class Database { }; /** - * @brief Represents an in-memory database for storing and managing atoms, nodes, and links. + * @brief Represents an in-memory database for storing and managing atoms, + * nodes, and links. * - * The InMemoryDB class inherits from the AtomDB class and provides an implementation for - * managing various types of data within an in-memory data structure. It supports operations - * such as adding, retrieving, and clearing atoms, nodes, links, and their relationships. + * The InMemoryDB class inherits from the AtomDB class and provides an + * implementation for managing various types of data within an in-memory data + * structure. It supports operations such as adding, retrieving, and clearing + * atoms, nodes, links, and their relationships. * - * This class uses unordered maps to store different types of data, including atom types, - * nodes, links, and sets for managing relationships between atoms. It is designed to be - * efficient for in-memory operations, making it suitable for applications that require - * fast access to data without the overhead of persistent storage. + * This class uses unordered maps to store different types of data, including + * atom types, nodes, links, and sets for managing relationships between atoms. + * It is designed to be efficient for in-memory operations, making it suitable + * for applications that require fast access to data without the overhead of + * persistent storage. * - * The InMemoryDB class is intended to be used in scenarios where data does not need to be - * persisted across sessions, or where the data can be reconstructed from other sources if - * needed. It provides a flexible and efficient way to manage complex data structures in - * memory. + * The InMemoryDB class is intended to be used in scenarios where data does not + * need to be persisted across sessions, or where the data can be reconstructed + * from other sources if needed. It provides a flexible and efficient way to + * manage complex data structures in memory. */ class InMemoryDB : public AtomDB { public: - InMemoryDB(const string& database_name = "das") : database_name(database_name) {}; - ~InMemoryDB() {}; + InMemoryDB(const string& database_name = "das") : database_name(database_name){}; + ~InMemoryDB(){}; const string get_node_handle(const string& node_type, const string& node_name) const override; @@ -191,8 +198,8 @@ class InMemoryDB : public AtomDB { * @brief Builds a hash for a named type template. * * This method takes a string representing a named type template and generates - * a hash for it. The hash can be used to uniquely identify the template within - * the database, ensuring efficient lookups and comparisons. + * a hash for it. The hash can be used to uniquely identify the template + * within the database, ensuring efficient lookups and comparisons. * * @param _template The string representation of the named type template. * @return A string containing the hash of the named type template. @@ -208,7 +215,8 @@ class InMemoryDB : public AtomDB { /** * @brief Retrieves and deletes the outgoing set associated with a handle. - * @param handle The handle for which the outgoing set is to be retrieved and deleted. + * @param handle The handle for which the outgoing set is to be retrieved and + * deleted. * @return An optional StringList containing the outgoing set if it exists. */ const optional _get_and_delete_outgoing_set(const string& handle); @@ -223,7 +231,8 @@ class InMemoryDB : public AtomDB { /** * @brief Deletes a set of incoming atoms associated with a given link handle. * @param link_handle A string representing the handle of the link. - * @param atoms_handles A list of strings representing the handles of the atoms to be deleted. + * @param atoms_handles A list of strings representing the handles of the + * atoms to be deleted. */ void _delete_incoming_set(const string& link_handle, const StringList& atoms_handles); @@ -239,7 +248,8 @@ class InMemoryDB : public AtomDB { /** * @brief Deletes templates associated with the given document link. - * @param link_document The link to the document whose templates are to be deleted. + * @param link_document The link to the document whose templates are to be + * deleted. */ void _delete_templates(const Link& link_document); @@ -253,8 +263,10 @@ class InMemoryDB : public AtomDB { /** * @brief Deletes patterns from the specified document. - * @param link_document The link to the document from which patterns will be deleted. - * @param targets_hash A list of hashes representing the patterns to be deleted. + * @param link_document The link to the document from which patterns will be + * deleted. + * @param targets_hash A list of hashes representing the patterns to be + * deleted. */ void _delete_patterns(const Link& link_document, const StringList& targets_hash); @@ -267,7 +279,8 @@ class InMemoryDB : public AtomDB { /** * @brief Filters out non-top-level elements from the given set of matches. * @param matches The set of matches to be filtered. - * @return A set containing only the top-level elements from the input matches. + * @return A set containing only the top-level elements from the input + * matches. */ const StringUnorderedSet _filter_non_toplevel(const StringUnorderedSet& matches) const; @@ -286,7 +299,8 @@ class InMemoryDB : public AtomDB { /** * @brief Updates the index for the given atom. * @param atom The atom to update the index for. - * @param delete_atom Flag indicating whether to delete the atom from the index. + * @param delete_atom Flag indicating whether to delete the atom from the + * index. */ void _update_index(const Atom& atom, bool delete_atom = false); }; diff --git a/src/hyperon_das_atomdb_cpp_lib/type_aliases.h b/src/hyperon_das_atomdb_cpp_lib/type_aliases.h index f9525f7..2bd38b8 100644 --- a/src/hyperon_das_atomdb_cpp_lib/type_aliases.h +++ b/src/hyperon_das_atomdb_cpp_lib/type_aliases.h @@ -1,18 +1,20 @@ /** * @file type_aliases.h - * @brief This header file contains type aliases to improve code readability and maintainability - * within the atomdb namespace. + * @brief This header file contains type aliases to improve code readability and + * maintainability within the atomdb namespace. * - * The type aliases defined in this file are intended to simplify the usage of commonly used - * STL containers and types, making the code more concise and easier to understand. The aliases - * cover a range of types including optional values, sets, maps, and lists. + * The type aliases defined in this file are intended to simplify the usage of + * commonly used STL containers and types, making the code more concise and + * easier to understand. The aliases cover a range of types including optional + * values, sets, maps, and lists. * - * @note 1. The alias MapOfAny for std::unordered_map is commented out due - * to poor performance. It is kept in the file as a reminder of the performance implications. - * 2. ListOfAny is an alias for std::vector, representing a list of any type. - * Note that while std::vector can be useful in some cases, its performance - * should be tested for each specific use case. + * @note 1. The alias MapOfAny for std::unordered_map is + * commented out due to poor performance. It is kept in the file as a reminder + * of the performance implications. + * 2. ListOfAny is an alias for std::vector, representing a list + * of any type. Note that while std::vector can be useful in some + * cases, its performance should be tested for each specific use case. */ #pragma once @@ -35,15 +37,17 @@ using StringList = vector; using StringUnorderedSet = unordered_set; /** - * std::vector performs well enough in some particular cases, but be cautious when using it. - * Always test how it performs in your specific use case. + * std::vector performs well enough in some particular cases, but be + * cautious when using it. Always test how it performs in your specific use + * case. */ using ListOfAny = vector; /** * NOTE: - * The following type alias was commented out because std::unordered_map performs - * poorly, and it was kept here just as a reminder of the performance implications. + * The following type alias was commented out because std::unordered_map performs poorly, and it was kept here just as a reminder of the + * performance implications. * * using MapOfAny = unordered_map; */ diff --git a/src/hyperon_das_node/hyperon_das_node_ext.cc b/src/hyperon_das_node/hyperon_das_node_ext.cc index 7d35344..a80ee33 100644 --- a/src/hyperon_das_node/hyperon_das_node_ext.cc +++ b/src/hyperon_das_node/hyperon_das_node_ext.cc @@ -1,16 +1,16 @@ #include +#include #include #include -#include #include #include "distributed_algorithm_node/DistributedAlgorithmNode.h" +#include "distributed_algorithm_node/LeadershipBroker.h" #include "distributed_algorithm_node/Message.h" #include "distributed_algorithm_node/MessageBroker.h" -#include "distributed_algorithm_node/LeadershipBroker.h" namespace nb = nanobind; -using namespace nb::literals; // Enables use of literal "_a" for named arguments +using namespace nb::literals; // Enables use of literal "_a" for named arguments using namespace std; using namespace distributed_algorithm_node; @@ -21,87 +21,89 @@ using MessageFactoryPtr = shared_ptr; // **************************** Python Trampolines **************************** // Trampolines allow Python subclasses to override C++ methods. -// For more information: https://nanobind.readthedocs.io/en/latest/classes.html#overriding-virtual-functions-in-python +// For more information: +// https://nanobind.readthedocs.io/en/latest/classes.html#overriding-virtual-functions-in-python class MessageTrampoline : public Message { - // Defines a trampoline for the BaseClass - // The count (1) denotes the total number of virtual method slots that can be - // overriden within Python. - NB_TRAMPOLINE(Message, 1); - void act(MessageFactoryPtr node) override { - // Allows Python to override a pure virtual method - NB_OVERRIDE_PURE(act, node); - } + // Defines a trampoline for the BaseClass + // The count (1) denotes the total number of virtual method slots that can be + // overriden within Python. + NB_TRAMPOLINE(Message, 1); + void act(MessageFactoryPtr node) override { + // Allows Python to override a pure virtual method + NB_OVERRIDE_PURE(act, node); + } }; class MessageFactoryTrampoline : public MessageFactory { -public: - NB_TRAMPOLINE(MessageFactory, 1); - MessagePtr message_factory(string &command, vector &args) override { - NB_OVERRIDE_PURE(message_factory, command, args); - }; + public: + NB_TRAMPOLINE(MessageFactory, 1); + MessagePtr message_factory(string& command, vector& args) override { + NB_OVERRIDE_PURE(message_factory, command, args); + }; }; class DistributedAlgorithmNodeTrampoline : public DistributedAlgorithmNode { -public: - // Defines a trampoline for the BaseClass - // Since we are overriding 3 methods in Python, thon - NB_TRAMPOLINE(DistributedAlgorithmNode, 3); - MessagePtr message_factory(string &command, vector &args) override { - // Allows Python to override a non pure virtual method - NB_OVERRIDE(message_factory, command, args); - }; - void node_joined_network(const string &node_id) override { - NB_OVERRIDE_PURE(node_joined_network, node_id); - }; - string cast_leadership_vote() override { - NB_OVERRIDE_PURE(cast_leadership_vote); - }; + public: + // Defines a trampoline for the BaseClass + // Since we are overriding 3 methods in Python, thon + NB_TRAMPOLINE(DistributedAlgorithmNode, 3); + MessagePtr message_factory(string& command, vector& args) override { + // Allows Python to override a non pure virtual method + NB_OVERRIDE(message_factory, command, args); + }; + void node_joined_network(const string& node_id) override { + NB_OVERRIDE_PURE(node_joined_network, node_id); + }; + string cast_leadership_vote() override { NB_OVERRIDE_PURE(cast_leadership_vote); }; }; // **************************************************************************** // Create the Python module 'hyperon_das_node_ext' NB_MODULE(hyperon_das_node_ext, m) { + // Message.h bindings + nb::class_(m, "Message") + .def(nb::init<>()) + .def("act", + &Message::act); // Bind the act method (can be overriden in Python) - // Message.h bindings - nb::class_(m, "Message") - .def(nb::init<>()) - .def("act", &Message::act); // Bind the act method (can be overriden in Python) - - nb::class_(m, "MessageFactory") - .def("message_factory", &MessageFactory::message_factory); // Bind the message_factory method (can be overriden in Python) + nb::class_(m, "MessageFactory") + .def("message_factory", + &MessageFactory::message_factory); // Bind the message_factory method + // (can be overriden in Python) - // LeadershipBroker.h bindings - // Binds the enum LeadershipBrokerType and all of it's values. - // Needs to be updated whenever a new LeadershipBrokerType is added. - nb::enum_(m, "LeadershipBrokerType") - .value("SINGLE_MASTER_SERVER", LeadershipBrokerType::SINGLE_MASTER_SERVER); + // LeadershipBroker.h bindings + // Binds the enum LeadershipBrokerType and all of it's values. + // Needs to be updated whenever a new LeadershipBrokerType is added. + nb::enum_(m, "LeadershipBrokerType") + .value("SINGLE_MASTER_SERVER", LeadershipBrokerType::SINGLE_MASTER_SERVER); - // MessageBroker.h bindings - // Binds the enum MessageBrokerType and all of it's values. - // Needs to be updated whenever a new MessageBrokerType is added. - nb::enum_(m, "MessageBrokerType") - .value("GRPC", MessageBrokerType::GRPC) - .value("RAM", MessageBrokerType::RAM); + // MessageBroker.h bindings + // Binds the enum MessageBrokerType and all of it's values. + // Needs to be updated whenever a new MessageBrokerType is added. + nb::enum_(m, "MessageBrokerType") + .value("GRPC", MessageBrokerType::GRPC) + .value("RAM", MessageBrokerType::RAM); - // DistributedAlgorithmNode.h bindings - nb::class_( - m, "DistributedAlgorithmNode") - .def(nb::init(), - "node_id"_a, "leadership_algorithm"_a, "messaging_backend"_a) - .def("join_network", &DistributedAlgorithmNode::join_network) - .def("is_leader", &DistributedAlgorithmNode::is_leader) - .def("leader_id", &DistributedAlgorithmNode::leader_id) - .def("has_leader", &DistributedAlgorithmNode::has_leader) - // Whenever we have a parameter that is a pointer or a reference, we need - // to specify the name of the argument. Otherwise nanobind will add a - // default arg0, arg1, etc. - .def("add_peer", &DistributedAlgorithmNode::add_peer, "peer_id"_a) - .def("node_id", &DistributedAlgorithmNode::node_id) - .def("broadcast", &DistributedAlgorithmNode::broadcast, "command"_a, "args"_a) - .def("send", &DistributedAlgorithmNode::send, "command"_a, "args"_a, "recipient"_a) - .def("node_joined_network", &DistributedAlgorithmNode::node_joined_network, - "node_id"_a) - .def("cast_leadership_vote", &DistributedAlgorithmNode::cast_leadership_vote) - .def("message_factory", &DistributedAlgorithmNode::message_factory); + // DistributedAlgorithmNode.h bindings + nb::class_( + m, "DistributedAlgorithmNode") + .def(nb::init(), + "node_id"_a, + "leadership_algorithm"_a, + "messaging_backend"_a) + .def("join_network", &DistributedAlgorithmNode::join_network) + .def("is_leader", &DistributedAlgorithmNode::is_leader) + .def("leader_id", &DistributedAlgorithmNode::leader_id) + .def("has_leader", &DistributedAlgorithmNode::has_leader) + // Whenever we have a parameter that is a pointer or a reference, we need + // to specify the name of the argument. Otherwise nanobind will add a + // default arg0, arg1, etc. + .def("add_peer", &DistributedAlgorithmNode::add_peer, "peer_id"_a) + .def("node_id", &DistributedAlgorithmNode::node_id) + .def("broadcast", &DistributedAlgorithmNode::broadcast, "command"_a, "args"_a) + .def("send", &DistributedAlgorithmNode::send, "command"_a, "args"_a, "recipient"_a) + .def("node_joined_network", &DistributedAlgorithmNode::node_joined_network, "node_id"_a) + .def("cast_leadership_vote", &DistributedAlgorithmNode::cast_leadership_vote) + .def("message_factory", &DistributedAlgorithmNode::message_factory); } diff --git a/src/inference_agent/inference_agent.h b/src/inference_agent/inference_agent.h index 1e9dc35..f251a19 100644 --- a/src/inference_agent/inference_agent.h +++ b/src/inference_agent/inference_agent.h @@ -3,16 +3,16 @@ */ #pragma once +#include #include #include #include #include #include -#include #include "das_link_creation_node.h" -#include "inference_node.h" #include "inference_iterator.h" +#include "inference_node.h" using namespace distributed_algorithm_node; using namespace link_creation_agent; @@ -23,9 +23,10 @@ class InferenceAgent { InferenceAgent(); ~InferenceAgent(); /** - * @brief Start the agent, receive inference request from the client, send link_creation - * request to the link_creation_agent, listen when distributed inference control agent - * finish the inference, send request to stop link creation. + * @brief Start the agent, receive inference request from the client, send + * link_creation request to the link_creation_agent, listen when distributed + * inference control agent finish the inference, send request to stop link + * creation. */ void run(); void stop(); @@ -47,10 +48,10 @@ class InferenceAgent { std::mutex agent_mutex; InferenceNode* inference_node_server; LinkCreationNode* link_creation_node_client; - std::unordered_map iterator_link_creation_request_map; // iterator_id, link_creation_request + std::unordered_map + iterator_link_creation_request_map; // iterator_id, link_creation_request std::vector>> inference_iterators; // DasAgentNode* das_client; // DistributedInferenceControlNode* distributed_inference_control_node; - }; } // namespace inference_agent diff --git a/src/inference_agent/inference_node.h b/src/inference_agent/inference_node.h index 508748f..5e49c8d 100644 --- a/src/inference_agent/inference_node.h +++ b/src/inference_agent/inference_node.h @@ -24,7 +24,6 @@ class InferenceNode : public StarNode { bool is_answers_empty(); string pop_answer(); - void send_message(std::vector args); virtual std::shared_ptr message_factory(std::string& command, @@ -44,7 +43,6 @@ class InferenceNode : public StarNode { std::mutex agent_node_mutex; }; - class CreateInferenceMessage : public Message { public: CreateInferenceMessage(std::string command, std::vector args); @@ -52,7 +50,6 @@ class CreateInferenceMessage : public Message { void act(std::shared_ptr node) override; }; - class InferenceAnswerMessage : public Message { public: InferenceAnswerMessage(std::string command, std::vector args); @@ -60,7 +57,6 @@ class InferenceAnswerMessage : public Message { void act(std::shared_ptr node) override; }; - class DistributedInferenceFinishedMessage : public Message { public: DistributedInferenceFinishedMessage(std::string command, std::vector args); diff --git a/src/inference_agent/inference_request.h b/src/inference_agent/inference_request.h index 07d3d8e..99749bd 100644 --- a/src/inference_agent/inference_request.h +++ b/src/inference_agent/inference_request.h @@ -72,7 +72,6 @@ class ProofOfImplication : public InferenceRequest { std::vector untokenize() override; std::vector query() override; - private: const std::string IMPLICATION_DEDUCTION_PROCESSOR = "IMPLICATION_DEDUCTION"; }; @@ -86,7 +85,6 @@ class ProofOfEquivalence : public InferenceRequest { std::vector untokenize() override; std::vector query() override; - private: const std::string EQUIVALENCE_DEDUCTION_PROCESSOR = "EQUIVALENCE_DEDUCTION"; }; diff --git a/src/link_creation_agent/das_link_creation_node.cc b/src/link_creation_agent/das_link_creation_node.cc index 8e3c7c4..2d30d79 100644 --- a/src/link_creation_agent/das_link_creation_node.cc +++ b/src/link_creation_agent/das_link_creation_node.cc @@ -4,11 +4,10 @@ using namespace link_creation_agent; using namespace std; using namespace distributed_algorithm_node; -LinkCreationNode::LinkCreationNode(const string& node_id) : StarNode(node_id) { - is_server = true; -} +LinkCreationNode::LinkCreationNode(const string& node_id) : StarNode(node_id) { is_server = true; } -LinkCreationNode::LinkCreationNode(const string& node_id, const string& server_id) : StarNode(node_id, server_id) { +LinkCreationNode::LinkCreationNode(const string& node_id, const string& server_id) + : StarNode(node_id, server_id) { is_server = false; } @@ -39,7 +38,6 @@ shared_ptr LinkCreationNode::message_factory(string& command, vector(command, args); } - void LinkCreationNode::send_message(vector args) { cout << "Sending message" << endl; send(CREATE_LINK, args, server_id); @@ -55,5 +53,3 @@ void LinkCreationRequest::act(shared_ptr node) { string request; link_node->add_request(this->args); } - - diff --git a/src/link_creation_agent/das_link_creation_node.h b/src/link_creation_agent/das_link_creation_node.h index 1af9b04..149a91d 100644 --- a/src/link_creation_agent/das_link_creation_node.h +++ b/src/link_creation_agent/das_link_creation_node.h @@ -20,7 +20,8 @@ class LinkCreationNode : public StarNode { * @param node_id ID of this node in the network. * @param server_id ID of a server. */ - LinkCreationNode(const string& node_id, const string& server_id);; + LinkCreationNode(const string& node_id, const string& server_id); + ; /** * Destructor @@ -57,7 +58,7 @@ class LinkCreationNode : public StarNode { private: Queue> shared_queue; const string CREATE_LINK = "create_link"; // DAS Node command - const string CREATE_LINK_PROCESSOR = "create_link_processor"; + const string CREATE_LINK_PROCESSOR = "create_link_processor"; bool shutting_down = false; bool is_server = true; }; diff --git a/src/link_creation_agent/link.cc b/src/link_creation_agent/link.cc index 839a5f0..3c24df3 100644 --- a/src/link_creation_agent/link.cc +++ b/src/link_creation_agent/link.cc @@ -6,8 +6,6 @@ using namespace link_creation_agent; using namespace std; using namespace query_engine; - - Link::Link(QueryAnswer* query_answer, vector link_template) { LinkCreateTemplate link_create_template(link_template); HandlesAnswer* handles_answer = dynamic_cast(query_answer); @@ -56,10 +54,9 @@ vector Link::get_targets() { return this->targets; } void Link::set_type(string type) { this->type = type; } - void Link::add_target(LinkTargetTypes target) { this->targets.push_back(target); } -vector Link::tokenize() { +vector Link::tokenize() { vector tokens; tokens.push_back("LINK"); tokens.push_back(this->type); diff --git a/src/link_creation_agent/link.h b/src/link_creation_agent/link.h index 46902c2..e1a259c 100644 --- a/src/link_creation_agent/link.h +++ b/src/link_creation_agent/link.h @@ -4,59 +4,56 @@ */ #pragma once #include -#include #include -#include "QueryAnswer.h" +#include + #include "HandlesAnswer.h" +#include "QueryAnswer.h" #include "link_create_template.h" using namespace std; using namespace query_engine; -namespace link_creation_agent -{ - - class Link; // forward declaration - - using LinkTargetTypes = std::variant>; - - class Link - { - public: - Link(QueryAnswer *query_answer, vector link_template); - Link(QueryAnswer *query_answer, shared_ptr link_create_template); - Link(); - ~Link(); - /** - * @brief Get the type of the link - * @returns Returns the type of the link - */ - string get_type(); - /** - * @brief Get the targets of the link - * @returns Returns the targets of the link - */ - vector get_targets(); - /** - * @brief Set the type of the link - */ - void set_type(string type); - /** - * @brief Add a target to the link - * @param target Target to be added - */ - void add_target(LinkTargetTypes target); - /** - * @brief Tokenize the link - * @returns Returns the tokenized link - */ - vector tokenize(); - - private: - string type; - vector targets; - vector custom_fields; - - - }; -} \ No newline at end of file +namespace link_creation_agent { + +class Link; // forward declaration + +using LinkTargetTypes = std::variant>; + +class Link { + public: + Link(QueryAnswer* query_answer, vector link_template); + Link(QueryAnswer* query_answer, shared_ptr link_create_template); + Link(); + ~Link(); + /** + * @brief Get the type of the link + * @returns Returns the type of the link + */ + string get_type(); + /** + * @brief Get the targets of the link + * @returns Returns the targets of the link + */ + vector get_targets(); + /** + * @brief Set the type of the link + */ + void set_type(string type); + /** + * @brief Add a target to the link + * @param target Target to be added + */ + void add_target(LinkTargetTypes target); + /** + * @brief Tokenize the link + * @returns Returns the tokenized link + */ + vector tokenize(); + + private: + string type; + vector targets; + vector custom_fields; +}; +} // namespace link_creation_agent \ No newline at end of file diff --git a/src/link_creation_agent/link_create_template.h b/src/link_creation_agent/link_create_template.h index 30d7d5a..fb99ad4 100644 --- a/src/link_creation_agent/link_create_template.h +++ b/src/link_creation_agent/link_create_template.h @@ -43,13 +43,14 @@ struct Variable { /** * @typedef CustomFieldTypes - * @brief A variant type that can hold either a std::string or a std::shared_ptr to a CustomField. + * @brief A variant type that can hold either a std::string or a std::shared_ptr + * to a CustomField. */ using CustomFieldTypes = std::variant>; /** * @typedef LinkCreateTemplateTypes - * @brief A variant type that can hold either a Variable, Node, or a std::shared_ptr to a - * LinkCreateTemplate. + * @brief A variant type that can hold either a Variable, Node, or a + * std::shared_ptr to a LinkCreateTemplate. */ using LinkCreateTemplateTypes = std::variant>; @@ -60,7 +61,8 @@ using LinkCreateTemplateTypes = std::variant& custom_fields); /** @@ -74,7 +76,8 @@ class CustomField { std::string get_name(); /** * @brief Gets the values of the custom field. - * @return A vector of tuples containing the name and value of the custom field. + * @return A vector of tuples containing the name and value of the custom + * field. */ std::vector> get_values(); /** @@ -95,12 +98,14 @@ class CustomField { /** * @class LinkCreateTemplate - * @brief Represents a link creation template with a link type, targets, and custom fields. + * @brief Represents a link creation template with a link type, targets, and + * custom fields. */ class LinkCreateTemplate { public: /** - * @brief Constructor that initializes the link creation template with a list of link templates. + * @brief Constructor that initializes the link creation template with a list + * of link templates. */ LinkCreateTemplate(std::vector& link_template); /** @@ -130,7 +135,8 @@ class LinkCreateTemplate { /** * @brief Tokenizes the link creation template. - * @return A vector of strings representing the tokenized link creation template. + * @return A vector of strings representing the tokenized link creation + * template. */ std::vector tokenize(); diff --git a/src/link_creation_agent/link_creation_agent.h b/src/link_creation_agent/link_creation_agent.h index da23bf5..4efa69f 100644 --- a/src/link_creation_agent/link_creation_agent.h +++ b/src/link_creation_agent/link_creation_agent.h @@ -40,11 +40,13 @@ struct LinkCreationAgentRequest { /** * @class LinkCreationAgent - * @brief Manages the creation of links by processing requests from the DAS Node server or buffer. + * @brief Manages the creation of links by processing requests from the DAS Node + * server or buffer. * - * This class is responsible for retrieving requests, sending query requests, processing iterators, - * and creating links using the LCAService. It also handles loading and saving configurations and - * request buffers, and managing the lifecycle of the agent. + * This class is responsible for retrieving requests, sending query requests, + * processing iterators, and creating links using the LCAService. It also + * handles loading and saving configurations and request buffers, and managing + * the lifecycle of the agent. */ class LinkCreationAgent { public: @@ -52,9 +54,10 @@ class LinkCreationAgent { ~LinkCreationAgent(); /** - * @brief Retrieve a request from DAS Node server or get a request from the requests buffer, - * send a query request using DAS Node client, retrieve remote iterator and - * send to LCAService to process the iterator and create links. + * @brief Retrieve a request from DAS Node server or get a request from the + * requests buffer, send a query request using DAS Node client, retrieve + * remote iterator and send to LCAService to process the iterator and create + * links. */ void run(); /** @@ -66,7 +69,8 @@ class LinkCreationAgent { private: /** * @brief Sends a query to DAS Query Agent - * @returns Returns a shared_ptr, to iterate through the requests + * @returns Returns a shared_ptr, to iterate through the + * requests */ shared_ptr> query(vector& query_tokens, string context, @@ -76,11 +80,13 @@ class LinkCreationAgent { */ void load_config(); /** - * @brief Save all requests that have the infinite value set as true to the disk or DB. + * @brief Save all requests that have the infinite value set as true to the + * disk or DB. */ void save_buffer(); /** - * @brief Load all requests that have the infinite value set as true from the disk or DB. + * @brief Load all requests that have the infinite value set as true from the + * disk or DB. */ void load_buffer(); /** @@ -97,8 +103,8 @@ class LinkCreationAgent { string link_creation_agent_server_id; // ID of the link creation server string das_agent_client_id; // ID of the DAS client string das_agent_server_id; - string requests_buffer_file; // Path to the requests buffer file - string context; // Context to send to attention broker + string requests_buffer_file; // Path to the requests buffer file + string context; // Context to send to attention broker // Other attributes LinkCreationService* service; diff --git a/src/link_creation_agent/queue.h b/src/link_creation_agent/queue.h index 9c80491..213435c 100644 --- a/src/link_creation_agent/queue.h +++ b/src/link_creation_agent/queue.h @@ -6,31 +6,27 @@ template class Queue { -private: + private: std::queue m_queue; std::mutex m_mutex; std::condition_variable m_cond; -public: - void enqueue(T item) - { - + public: + void enqueue(T item) { std::unique_lock lock(m_mutex); m_queue.push(item); m_cond.notify_one(); } - T dequeue() - { + T dequeue() { std::unique_lock lock(m_mutex); - m_cond.wait(lock, - [this]() { return !m_queue.empty(); }); + m_cond.wait(lock, [this]() { return !m_queue.empty(); }); T item = m_queue.front(); m_queue.pop(); return item; } - bool empty(){ + bool empty() { bool answer; std::unique_lock lock(m_mutex); answer = m_queue.empty(); diff --git a/src/main/attention_broker_main.cc b/src/main/attention_broker_main.cc index a85bd84..fc8aca1 100644 --- a/src/main/attention_broker_main.cc +++ b/src/main/attention_broker_main.cc @@ -1,19 +1,17 @@ -#include -#include - #include #include #include - #include -#include "common.pb.h" -#include "attention_broker.grpc.pb.h" -#include "attention_broker.pb.h" +#include +#include #include "AttentionBrokerServer.h" +#include "attention_broker.grpc.pb.h" +#include "attention_broker.pb.h" +#include "common.pb.h" -//attention_broker_server::AttentionBrokerServer service; +// attention_broker_server::AttentionBrokerServer service; /* void ctrl_c_handler(int) { @@ -27,8 +25,8 @@ void ctrl_c_handler(int) { void run_server(unsigned int port) { attention_broker_server::AttentionBrokerServer service; std::string server_address = "localhost:" + to_string(port); - //grpc::EnableDefaultHealthCheckService(true); - //grpc::reflection::InitProtoReflectionServerBuilderPlugin(); + // grpc::EnableDefaultHealthCheckService(true); + // grpc::reflection::InitProtoReflectionServerBuilderPlugin(); ServerBuilder builder; builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); builder.RegisterService(&service); @@ -44,7 +42,7 @@ int main(int argc, char* argv[]) { exit(1); } unsigned int port = stoi(argv[1]); - //signal(SIGINT, &ctrl_c_handler); + // signal(SIGINT, &ctrl_c_handler); run_server(port); return 0; } diff --git a/src/main/inference_agent_main.cc b/src/main/inference_agent_main.cc index 2d7aeea..965ed82 100644 --- a/src/main/inference_agent_main.cc +++ b/src/main/inference_agent_main.cc @@ -2,7 +2,6 @@ using namespace inference_agent; - int main() { // InferenceAgent agent; // agent.run(); diff --git a/src/main/link_creation_agent_client_main.cc b/src/main/link_creation_agent_client_main.cc index afeab4a..2c45d52 100644 --- a/src/main/link_creation_agent_client_main.cc +++ b/src/main/link_creation_agent_client_main.cc @@ -14,7 +14,6 @@ void ctrl_c_handler(int) { exit(0); } - int main(int argc, char* argv[]) { string help = R""""( Usage: link_creation_agent CLIENT_HOST:CLIENT_PORT SERVER_HOST:SERVER_PORT REQUEST+ diff --git a/src/main/link_creation_agent_main.cc b/src/main/link_creation_agent_main.cc index 8504889..a02c1b2 100644 --- a/src/main/link_creation_agent_main.cc +++ b/src/main/link_creation_agent_main.cc @@ -1,7 +1,8 @@ -#include -#include #include + #include +#include +#include #include "link_creation_agent.h" using namespace link_creation_agent; @@ -13,8 +14,6 @@ void ctrl_c_handler(int) { exit(0); } - - /** * @brief Main function * Reads the config file and starts the DAS NODE client/server @@ -22,8 +21,7 @@ void ctrl_c_handler(int) { * @param argv Arguments * @returns Returns 0 if the program runs successfully */ -int main(int argc, char *argv[]) -{ +int main(int argc, char* argv[]) { string help = R""""( Usage: link_creation_agent --config_file --type Suported args: @@ -37,12 +35,10 @@ int main(int argc, char *argv[]) QUERY, LINK_TEMPLATE, MAX_RESULTS, REPEAT MAX_RESULTS and REPEAT are optional, the default value for MAX_RESULTS is 1000 and for REPEAT is 1 )""""; - - if ((argc < 4) ) - { + + if ((argc < 4)) { cerr << help << endl; - for (auto arg = 0; arg < argc; arg++) - { + for (auto arg = 0; arg < argc; arg++) { cerr << "arg[" << arg << "] = " << argv[arg] << endl; } exit(1); @@ -50,13 +46,10 @@ int main(int argc, char *argv[]) signal(SIGINT, &ctrl_c_handler); string type = argv[2]; string config_path = argv[4]; - - if (type == "client") - { + + if (type == "client") { cerr << "Client not implemented yet" << endl; - } - else - { + } else { cout << "Starting server" << endl; auto server = new LinkCreationAgent(config_path); server->run(); diff --git a/src/main/link_creation_engine_main.cc b/src/main/link_creation_engine_main.cc index 5638695..0742031 100644 --- a/src/main/link_creation_engine_main.cc +++ b/src/main/link_creation_engine_main.cc @@ -1,14 +1,14 @@ +#include + #include -#include #include +#include -#include - +#include "AtomDB.h" +#include "AtomDBSingleton.h" #include "DASNode.h" -#include "RemoteIterator.h" #include "QueryAnswer.h" -#include "AtomDBSingleton.h" -#include "AtomDB.h" +#include "RemoteIterator.h" #include "Utils.h" #define MAX_QUERY_ANSWERS ((unsigned int) 1000) @@ -35,8 +35,7 @@ std::vector split(string s, string delimiter) { return tokens; } -double compute_sim1(const vector &tokens1, const vector &tokens2) { - +double compute_sim1(const vector& tokens1, const vector& tokens2) { unsigned int count = 0; /* @@ -55,8 +54,8 @@ double compute_sim1(const vector &tokens1, const vector &tokens2 } */ - for (auto token1: tokens1) { - for (auto token2: tokens2) { + for (auto token1 : tokens1) { + for (auto token2 : tokens2) { if (token1 == token2) { count++; break; @@ -64,8 +63,8 @@ double compute_sim1(const vector &tokens1, const vector &tokens2 } } - for (auto token2: tokens2) { - for (auto token1: tokens1) { + for (auto token2 : tokens2) { + for (auto token1 : tokens1) { if (token2 == token1) { count++; break; @@ -76,8 +75,7 @@ double compute_sim1(const vector &tokens1, const vector &tokens2 return ((1.0) * count) / (tokens1.size() + tokens2.size()); } -double compute_sim2(const vector &tokens1, const vector &tokens2) { - +double compute_sim2(const vector& tokens1, const vector& tokens2) { if (tokens1.size() != tokens2.size()) { return 0.0; } @@ -94,15 +92,17 @@ double compute_sim2(const vector &tokens1, const vector &tokens2 return (1.0 * count) / total_length; } -string highlight(const vector &tokens1, const vector &tokens2, const set &highlighted) { - //printf("\033[31;1;4mHello\033[0m"); +string highlight(const vector& tokens1, + const vector& tokens2, + const set& highlighted) { + // printf("\033[31;1;4mHello\033[0m"); string answer = ""; bool token_flag, char_flag, word_flag; for (unsigned int i = 0; i < tokens1.size(); i++) { token_flag = (highlighted.find(tokens1[i]) != highlighted.end()); word_flag = false; if (highlighted.size() == 0) { - for (auto token: tokens2) { + for (auto token : tokens2) { if (tokens1[i] == token) { word_flag = true; break; @@ -115,7 +115,7 @@ string highlight(const vector &tokens1, const vector &tokens2, c } else { char_flag = false; } - char_flag = false; // XXXXX + char_flag = false; // XXXXX if (token_flag || char_flag || word_flag) { answer += "\033["; if (token_flag) { @@ -147,8 +147,12 @@ string highlight(const vector &tokens1, const vector &tokens2, c return answer; } -void build_link(const string &link_type_tag, const string str1, const string str2, double threshold, stack &output, const set &highlighted) { - +void build_link(const string& link_type_tag, + const string str1, + const string str2, + double threshold, + stack& output, + const set& highlighted) { string sentence1 = str1.substr(1, str1.size() - 2); string sentence2 = str2.substr(1, str2.size() - 2); @@ -156,21 +160,21 @@ void build_link(const string &link_type_tag, const string str1, const string str vector tokens2 = split(sentence2, " "); double v1 = compute_sim1(tokens1, tokens2); - //double v2 = compute_sim2(tokens1, tokens2); + // double v2 = compute_sim2(tokens1, tokens2); if (v1 >= threshold) { - //output.push(std::to_string(v1) + ": " + highlight(tokens1, tokens2, highlighted)); - //output.push(std::to_string(v2) + ": " + highlight(tokens2, tokens1, highlighted)); + // output.push(std::to_string(v1) + ": " + highlight(tokens1, tokens2, + // highlighted)); output.push(std::to_string(v2) + ": " + highlight(tokens2, + // tokens1, highlighted)); output.push(highlight(tokens1, tokens2, highlighted)); output.push(highlight(tokens2, tokens1, highlighted)); } } -string handle_to_atom(const char *handle) { - +string handle_to_atom(const char* handle) { shared_ptr db = AtomDBSingleton::get_instance(); shared_ptr document = db->get_atom_document(handle); - shared_ptr targets = db->query_for_targets((char *) handle); + shared_ptr targets = db->query_for_targets((char*) handle); string answer; if (targets != NULL) { @@ -197,11 +201,7 @@ string handle_to_atom(const char *handle) { return answer; } -void run( - const string &context, - const string &link_type_tag, - const set highlighted) { - +void run(const string& context, const string& link_type_tag, const set highlighted) { string server_id = "localhost:31700"; string client_id = "localhost:31701"; @@ -229,30 +229,29 @@ void run( // (Contains (Sentence "aef cbe dfb fbe eca eff bad") (Word "eff")) vector query_same_word = { - and_operator, "2", - link_template, expression, "3", - node, symbol, contains, - variable, sentence1, - variable, word1, - link_template, expression, "3", - node, symbol, contains, - variable, sentence2, - variable, word1 - }; - - vector query_same_size { - or_operator, "1", - link_template, expression, "4", - node, symbol, similarity, - variable, sentence1, - variable, sentence2, - variable, tv1 - }; + and_operator, "2", link_template, expression, "3", node, symbol, contains, + variable, sentence1, variable, word1, link_template, expression, "3", node, + symbol, contains, variable, sentence2, variable, word1}; + + vector query_same_size{or_operator, + "1", + link_template, + expression, + "4", + node, + symbol, + similarity, + variable, + sentence1, + variable, + sentence2, + variable, + tv1}; DASNode client(client_id, server_id); - QueryAnswer *query_answer; + QueryAnswer* query_answer; unsigned int count = 0; - RemoteIterator *response; + RemoteIterator* response; if (link_type_tag == "LINK1") { response = client.pattern_matcher_query(query_same_word, context); @@ -268,23 +267,24 @@ void run( shared_ptr sentence_symbol_document2; stack output; set already_inserted_links; - while (! response->finished()) { + while (!response->finished()) { if ((query_answer = response->pop()) == NULL) { Utils::sleep(); } else { - if (! strcmp(query_answer->assignment.get(sentence1.c_str()), query_answer->assignment.get(sentence2.c_str()))) { + if (!strcmp(query_answer->assignment.get(sentence1.c_str()), + query_answer->assignment.get(sentence2.c_str()))) { continue; } - //cout << query_answer->to_string() << endl; - //cout << handle_to_atom(query_answer->handles[0]) << endl; - //cout << handle_to_atom(query_answer->handles[1]) << endl; + // cout << query_answer->to_string() << endl; + // cout << handle_to_atom(query_answer->handles[0]) << endl; + // cout << handle_to_atom(query_answer->handles[1]) << endl; sentence_document1 = db->get_atom_document(query_answer->assignment.get(sentence1.c_str())); sentence_document2 = db->get_atom_document(query_answer->assignment.get(sentence2.c_str())); sentence_symbol_document1 = db->get_atom_document(sentence_document1->get("targets", 1)); sentence_symbol_document2 = db->get_atom_document(sentence_document2->get("targets", 1)); string s1 = string(sentence_symbol_document1->get("name")); string s2 = string(sentence_symbol_document2->get("name")); - if ((already_inserted_links.find(s1 + s2) == already_inserted_links.end()) && + if ((already_inserted_links.find(s1 + s2) == already_inserted_links.end()) && (already_inserted_links.find(s2 + s1) == already_inserted_links.end())) { build_link(link_type_tag, s1, s2, 0.0, output, highlighted); already_inserted_links.insert(s1 + s2); @@ -299,7 +299,7 @@ void run( if (count == 0) { cout << "No match for query" << endl; } else { - while (! output.empty()) { + while (!output.empty()) { cout << output.top() << endl; output.pop(); cout << output.top() << endl; @@ -312,7 +312,6 @@ void run( } int main(int argc, char* argv[]) { - if (argc < 3) { cerr << "Usage: " << argv[0] << " *" << endl; exit(1); diff --git a/src/main/query_client_main.cc b/src/main/query_client_main.cc index 3759e6d..5f87983 100644 --- a/src/main/query_client_main.cc +++ b/src/main/query_client_main.cc @@ -1,13 +1,13 @@ +#include + #include #include -#include - +#include "AtomDBSingleton.h" #include "DASNode.h" -#include "RemoteIterator.h" -#include "QueryAnswer.h" #include "HandlesAnswer.h" -#include "AtomDBSingleton.h" +#include "QueryAnswer.h" +#include "RemoteIterator.h" #include "Utils.h" #define MAX_QUERY_ANSWERS ((unsigned int) 1000) @@ -21,9 +21,12 @@ void ctrl_c_handler(int) { } int main(int argc, char* argv[]) { - if (argc < 4) { - cerr << "Usage: " << argv[0] << " CLIENT_HOST:CLIENT_PORT SERVER_HOST:SERVER_PORT QUERY_TOKEN+ (hosts are supposed to be public IPs or known hostnames)" << endl; + cerr << "Usage: " << argv[0] + << " CLIENT_HOST:CLIENT_PORT SERVER_HOST:SERVER_PORT QUERY_TOKEN+ " + "(hosts are supposed to " + "be public IPs or known hostnames)" + << endl; exit(1); } @@ -37,10 +40,10 @@ int main(int argc, char* argv[]) { } DASNode client(client_id, server_id); - QueryAnswer *query_answer; + QueryAnswer* query_answer; unsigned int count = 0; - RemoteIterator *response = client.pattern_matcher_query(query); - while (! response->finished()) { + RemoteIterator* response = client.pattern_matcher_query(query); + while (!response->finished()) { if ((query_answer = response->pop()) == NULL) { Utils::sleep(); } else { diff --git a/src/main/query_engine_main.cc b/src/main/query_engine_main.cc index c60f71c..3f5ac80 100644 --- a/src/main/query_engine_main.cc +++ b/src/main/query_engine_main.cc @@ -1,23 +1,22 @@ +#include + #include #include -#include - #include "AtomDBSingleton.h" -#include "Utils.h" #include "DASNode.h" +#include "Utils.h" using namespace std; void ctrl_c_handler(int) { - //std::cout << "Stopping query engine server..." << std::endl; + // std::cout << "Stopping query engine server..." << std::endl; std::cout << "Cleaning GRPC buffers..." << std::endl; std::cout << "Done." << std::endl; exit(0); } int main(int argc, char* argv[]) { - if (argc != 2) { cerr << "Usage: " << argv[0] << "" << endl; exit(1); @@ -27,7 +26,9 @@ int main(int argc, char* argv[]) { signal(SIGINT, &ctrl_c_handler); AtomDBSingleton::init(); DASNode server(server_id); - cout << "############################# REQUEST QUEUE EMPTY ##################################" << endl; + cout << "############################# REQUEST QUEUE EMPTY " + "##################################" + << endl; do { Utils::sleep(1000); } while (true); diff --git a/src/main/word_query_main.cc b/src/main/word_query_main.cc index de3b887..10aca6b 100644 --- a/src/main/word_query_main.cc +++ b/src/main/word_query_main.cc @@ -1,14 +1,14 @@ +#include + #include #include -#include - +#include "AtomDB.h" +#include "AtomDBSingleton.h" +#include "CountAnswer.h" #include "DASNode.h" -#include "RemoteIterator.h" #include "HandlesAnswer.h" -#include "CountAnswer.h" -#include "AtomDBSingleton.h" -#include "AtomDB.h" +#include "RemoteIterator.h" #include "Utils.h" #define MAX_QUERY_ANSWERS ((unsigned int) 500) @@ -35,7 +35,7 @@ std::vector split(string s, string delimiter) { return tokens; } -string highlight(const string &s, const set &highlighted) { +string highlight(const string& s, const set& highlighted) { vector tokens = split(s.substr(1, s.size() - 2), " "); string answer = ""; for (unsigned int i = 0; i < tokens.size(); i++) { @@ -52,13 +52,10 @@ string highlight(const string &s, const set &highlighted) { return answer; } - - -string handle_to_atom(const char *handle) { - +string handle_to_atom(const char* handle) { shared_ptr db = AtomDBSingleton::get_instance(); shared_ptr document = db->get_atom_document(handle); - shared_ptr targets = db->query_for_targets((char *) handle); + shared_ptr targets = db->query_for_targets((char*) handle); string answer; if (targets != NULL) { @@ -85,10 +82,7 @@ string handle_to_atom(const char *handle) { return answer; } -void run( - const string &context, - const string &word_tag) { - +void run(const string& context, const string& word_tag) { string server_id = "localhost:31700"; string client_id = "localhost:31701"; @@ -110,38 +104,47 @@ void run( string word1 = "word1"; string word2 = "word2"; - vector query_word = { - link_template, expression, "3", - node, symbol, contains, - variable, sentence1, - link, expression, "2", - node, symbol, word, - node, symbol, "\"" + word_tag + "\"" - }; + vector query_word = {link_template, + expression, + "3", + node, + symbol, + contains, + variable, + sentence1, + link, + expression, + "2", + node, + symbol, + word, + node, + symbol, + "\"" + word_tag + "\""}; DASNode client(client_id, server_id); - - HandlesAnswer *query_answer; + + HandlesAnswer* query_answer; unsigned int count = 0; auto response = unique_ptr>( client.pattern_matcher_query(query_word, context, true)); shared_ptr sentence_document; shared_ptr sentence_name_document; vector sentences; - while (! response->finished()) { + while (!response->finished()) { if ((query_answer = dynamic_cast(response->pop())) == NULL) { Utils::sleep(); } else { - //cout << "------------------------------------------" << endl; - //cout << query_answer->to_string() << endl; - const char *handle; + // cout << "------------------------------------------" << endl; + // cout << query_answer->to_string() << endl; + const char* handle; handle = query_answer->assignment.get(sentence1.c_str()); - //cout << string(handle) << endl; - //cout << handle_to_atom(handle) << endl; + // cout << string(handle) << endl; + // cout << handle_to_atom(handle) << endl; sentence_document = db->get_atom_document(handle); handle = sentence_document->get("targets", 1); - //cout << string(handle) << endl; - //cout << handle_to_atom(handle) << endl; + // cout << string(handle) << endl; + // cout << handle_to_atom(handle) << endl; sentence_name_document = db->get_atom_document(handle); // cout << string(sentence_name_document->get("name")) << endl; set to_highlight; @@ -149,11 +152,8 @@ void run( string sentence_name = string(sentence_name_document->get("name")); string highlighted_sentence_name = highlight(sentence_name, to_highlight); string w = "\"" + word_tag + "\""; - string line = "(Contains (Sentence " + - highlighted_sentence_name + - ") (Word \"" + - highlight(w, to_highlight) + - "\"))"; + string line = "(Contains (Sentence " + highlighted_sentence_name + ") (Word \"" + + highlight(w, to_highlight) + "\"))"; cout << line << endl; if (++count == MAX_QUERY_ANSWERS) { break; @@ -172,7 +172,6 @@ void run( } int main(int argc, char* argv[]) { - if (argc < 3) { cerr << "Usage: " << argv[0] << " " << endl; exit(1); diff --git a/src/query_engine/AtomDB.cc b/src/query_engine/AtomDB.cc index cd62f9b..aa8680a 100644 --- a/src/query_engine/AtomDB.cc +++ b/src/query_engine/AtomDB.cc @@ -1,13 +1,15 @@ -#include +#include "AtomDB.h" + +#include + #include -#include +#include #include -#include "AtomDB.h" -#include "Utils.h" +#include #include "AttentionBrokerServer.h" +#include "Utils.h" #include "attention_broker.grpc.pb.h" -#include #include "attention_broker.pb.h" using namespace query_engine; @@ -34,20 +36,18 @@ AtomDB::~AtomDB() { redisFree(this->redis_single); } delete this->mongodb_pool; - // delete this->mongodb_client; + // delete this->mongodb_client; } void AtomDB::attention_broker_setup() { - grpc::ClientContext context; grpc::Status status; dasproto::Empty empty; dasproto::Ack ack; string attention_broker_address = "localhost:37007"; - auto stub = dasproto::AttentionBroker::NewStub(grpc::CreateChannel( - attention_broker_address, - grpc::InsecureChannelCredentials())); + auto stub = dasproto::AttentionBroker::NewStub( + grpc::CreateChannel(attention_broker_address, grpc::InsecureChannelCredentials())); status = stub->ping(&context, empty, &ack); if (status.ok()) { std::cout << "Connected to AttentionBroker at " << attention_broker_address << endl; @@ -60,7 +60,6 @@ void AtomDB::attention_broker_setup() { } void AtomDB::redis_setup() { - string host = Utils::get_environment("DAS_REDIS_HOSTNAME"); string port = Utils::get_environment("DAS_REDIS_PORT"); string address = host + ":" + port; @@ -69,7 +68,10 @@ void AtomDB::redis_setup() { this->cluster_flag = (cluster == "TRUE"); if (host == "" || port == "") { - Utils::error("You need to set Redis access info as environment variables: DAS_REDIS_HOSTNAME, DAS_REDIS_PORT and DAS_USE_REDIS_CLUSTER"); + Utils::error( + "You need to set Redis access info as environment variables: " + "DAS_REDIS_HOSTNAME, " + "DAS_REDIS_PORT and DAS_USE_REDIS_CLUSTER"); } string cluster_tag = (this->cluster_flag ? "CLUSTER" : "NON-CLUSTER"); @@ -83,7 +85,7 @@ void AtomDB::redis_setup() { if (this->redis_cluster == NULL && this->redis_single == NULL) { Utils::error("Connection error."); - } else if ((! this->cluster_flag) && this->redis_single->err) { + } else if ((!this->cluster_flag) && this->redis_single->err) { Utils::error("Redis error: " + string(this->redis_single->errstr)); } else if (this->cluster_flag && this->redis_cluster->err) { Utils::error("Redis cluster error: " + string(this->redis_cluster->errstr)); @@ -92,20 +94,20 @@ void AtomDB::redis_setup() { } } -mongocxx::database AtomDB::get_database(){ +mongocxx::database AtomDB::get_database() { auto database = this->mongodb_pool->acquire(); return database[MONGODB_DB_NAME]; } void AtomDB::mongodb_setup() { - string host = Utils::get_environment("DAS_MONGODB_HOSTNAME"); string port = Utils::get_environment("DAS_MONGODB_PORT"); string user = Utils::get_environment("DAS_MONGODB_USERNAME"); string password = Utils::get_environment("DAS_MONGODB_PASSWORD"); if (host == "" || port == "" || user == "" || password == "") { - Utils::error(string("You need to set MongoDB access info as environment variables: ") + \ - "DAS_MONGODB_HOSTNAME, DAS_MONGODB_PORT, DAS_MONGODB_USERNAME and DAS_MONGODB_PASSWORD"); + Utils::error(string("You need to set MongoDB access info as environment variables: ") + + "DAS_MONGODB_HOSTNAME, DAS_MONGODB_PORT, DAS_MONGODB_USERNAME and " + "DAS_MONGODB_PASSWORD"); } string address = host + ":" + port; string url = "mongodb://" + user + ":" + password + "@" + address; @@ -118,11 +120,13 @@ void AtomDB::mongodb_setup() { // this->mongodb_client = new mongocxx::client(uri); // this->mongodb = (*this->mongodb_client)[MONGODB_DB_NAME]; - const auto ping_cmd = bsoncxx::builder::basic::make_document(bsoncxx::builder::basic::kvp("ping", 1)); + const auto ping_cmd = + bsoncxx::builder::basic::make_document(bsoncxx::builder::basic::kvp("ping", 1)); this->mongodb.run_command(ping_cmd.view()); this->mongodb_collection = this->mongodb[MONGODB_COLLECTION_NAME]; - //auto atom_count = this->mongodb_collection.count_documents({}); - //std::cout << "Connected to MongoDB at " << address << " Atom count: " << atom_count << endl; + // auto atom_count = this->mongodb_collection.count_documents({}); + // std::cout << "Connected to MongoDB at " << address << " Atom count: " << + // atom_count << endl; std::cout << "Connected to MongoDB at " << address << endl; } catch (const std::exception& e) { Utils::error(e.what()); @@ -130,14 +134,16 @@ void AtomDB::mongodb_setup() { } shared_ptr AtomDB::query_for_pattern(shared_ptr pattern_handle) { - redisReply *reply = (redisReply *) redisCommand(this->redis_single, "SMEMBERS %s:%s", REDIS_PATTERNS_PREFIX.c_str(), pattern_handle.get()); + redisReply* reply = (redisReply*) redisCommand( + this->redis_single, "SMEMBERS %s:%s", REDIS_PATTERNS_PREFIX.c_str(), pattern_handle.get()); if (reply == NULL) { Utils::error("Redis error"); } if (reply->type != REDIS_REPLY_SET && reply->type != REDIS_REPLY_ARRAY) { Utils::error("Invalid Redis response: " + std::to_string(reply->type)); } - // NOTE: Intentionally, we aren't destroying 'reply' objects.'reply' objects are destroyed in ~RedisSet(). + // NOTE: Intentionally, we aren't destroying 'reply' objects.'reply' objects + // are destroyed in ~RedisSet(). return shared_ptr(new atomdb_api_types::RedisSet(reply)); } @@ -145,8 +151,9 @@ shared_ptr AtomDB::query_for_targets(shared_ptr AtomDB::query_for_targets(char *link_handle_ptr) { - redisReply *reply = (redisReply *) redisCommand(this->redis_single, "GET %s:%s", REDIS_TARGETS_PREFIX.c_str(), link_handle_ptr); +shared_ptr AtomDB::query_for_targets(char* link_handle_ptr) { + redisReply* reply = (redisReply*) redisCommand( + this->redis_single, "GET %s:%s", REDIS_TARGETS_PREFIX.c_str(), link_handle_ptr); /* if (reply == NULL) { Utils::error("Redis error"); @@ -157,19 +164,21 @@ shared_ptr AtomDB::query_for_targets(char *link_ha } if (reply->type != REDIS_REPLY_STRING) { Utils::error("Invalid Redis response: " + std::to_string(reply->type) + - " != " + std::to_string(REDIS_REPLY_STRING)); + " != " + std::to_string(REDIS_REPLY_STRING)); } - // NOTE: Intentionally, we aren't destroying 'reply' objects.'reply' objects are destroyed in ~RedisSet(). - return shared_ptr(new atomdb_api_types::RedisStringBundle(reply)); + // NOTE: Intentionally, we aren't destroying 'reply' objects.'reply' objects + // are destroyed in ~RedisSet(). + return shared_ptr( + new atomdb_api_types::RedisStringBundle(reply)); } -shared_ptr AtomDB::get_atom_document(const char *handle) { +shared_ptr AtomDB::get_atom_document(const char* handle) { this->mongodb_mutex.lock(); auto mongodb_collection = get_database()[MONGODB_COLLECTION_NAME]; - auto reply = mongodb_collection.find_one( - bsoncxx::v_noabi::builder::basic::make_document( - bsoncxx::v_noabi::builder::basic::kvp(MONGODB_FIELD_NAME[MONGODB_FIELD::ID], handle))); - //cout << bsoncxx::to_json(*reply) << endl; // Note to reviewer: please let this dead code here + auto reply = mongodb_collection.find_one(bsoncxx::v_noabi::builder::basic::make_document( + bsoncxx::v_noabi::builder::basic::kvp(MONGODB_FIELD_NAME[MONGODB_FIELD::ID], handle))); + // cout << bsoncxx::to_json(*reply) << endl; // Note to reviewer: please let + // this dead code here this->mongodb_mutex.unlock(); return shared_ptr(new atomdb_api_types::MongodbDocument(reply)); } diff --git a/src/query_engine/AtomDB.h b/src/query_engine/AtomDB.h index 9a62b72..b039409 100644 --- a/src/query_engine/AtomDB.h +++ b/src/query_engine/AtomDB.h @@ -1,45 +1,44 @@ #ifndef _QUERY_ENGINE_ATOMDB_H #define _QUERY_ENGINE_ATOMDB_H -#include -#include -#include #include + #include +#include #include -#include #include +#include +#include +#include + #include "AtomDBAPITypes.h" using namespace std; namespace query_engine { - -enum MONGODB_FIELD { - ID = 0, - size -}; +enum MONGODB_FIELD { ID = 0, size }; // ------------------------------------------------------------------------------------------------- // NOTE TO REVIEWER: // -// This class will be replaced/integrated by/with classes already implemented in das-atom-db. -// -// However, that classes will need to be revisited in order to allow the methods implemented here -// because although the design of such methods is nasty, they have the string advantage of -// allowing the reuse of structures allocated by the DBMS (Redis an MongoDB) withpout the need -// of re-allocation of other dataclasses. Although this nasty behavior may not be desirable -// outside the DAS bounds, it's quite appealing inside the query engine (and perhaps other +// This class will be replaced/integrated by/with classes already implemented in +// das-atom-db. +// +// However, that classes will need to be revisited in order to allow the methods +// implemented here because although the design of such methods is nasty, they +// have the string advantage of allowing the reuse of structures allocated by +// the DBMS (Redis an MongoDB) withpout the need of re-allocation of other +// dataclasses. Although this nasty behavior may not be desirable outside the +// DAS bounds, it's quite appealing inside the query engine (and perhaps other // parts of internal stuff). // -// I think it's pointless to make any further documentation while we don't make this integrfation. +// I think it's pointless to make any further documentation while we don't make +// this integrfation. // ------------------------------------------------------------------------------------------------- class AtomDB { - -public: - + public: AtomDB(); ~AtomDB(); @@ -61,19 +60,18 @@ class AtomDB { shared_ptr query_for_pattern(shared_ptr pattern_handle); shared_ptr query_for_targets(shared_ptr link_handle); - shared_ptr query_for_targets(char *link_handle_ptr); - shared_ptr get_atom_document(const char *handle); - -private: + shared_ptr query_for_targets(char* link_handle_ptr); + shared_ptr get_atom_document(const char* handle); + private: bool cluster_flag; - redisClusterContext *redis_cluster; - redisContext *redis_single; - mongocxx::client *mongodb_client; + redisClusterContext* redis_cluster; + redisContext* redis_single; + mongocxx::client* mongodb_client; mongocxx::database mongodb; mongocxx::v_noabi::collection mongodb_collection; mutex mongodb_mutex; - mongocxx::pool *mongodb_pool; + mongocxx::pool* mongodb_pool; mongocxx::database get_database(); @@ -82,6 +80,6 @@ class AtomDB { void attention_broker_setup(); }; -} // namespace query_engine +} // namespace query_engine -#endif // _QUERY_ENGINE_ATOMDB_H +#endif // _QUERY_ENGINE_ATOMDB_H diff --git a/src/query_engine/AtomDBAPITypes.cc b/src/query_engine/AtomDBAPITypes.cc index 2d1a91b..4583b6f 100644 --- a/src/query_engine/AtomDBAPITypes.cc +++ b/src/query_engine/AtomDBAPITypes.cc @@ -1,43 +1,43 @@ +#include "AtomDBAPITypes.h" + #include #include "Utils.h" #include "expression_hasher.h" -#include "AtomDBAPITypes.h" using namespace query_engine; using namespace atomdb_api_types; using namespace commons; -RedisSet::RedisSet(redisReply *reply) : HandleList() { +RedisSet::RedisSet(redisReply* reply) : HandleList() { this->redis_reply = reply; this->handles_size = reply->elements; - this->handles = new char *[this->handles_size]; + this->handles = new char*[this->handles_size]; for (unsigned int i = 0; i < this->handles_size; i++) { handles[i] = reply->element[i]->str; } } RedisSet::~RedisSet() { - delete [] this->handles; + delete[] this->handles; freeReplyObject(this->redis_reply); } -const char *RedisSet::get_handle(unsigned int index) { +const char* RedisSet::get_handle(unsigned int index) { if (index > this->handles_size) { - Utils::error("Handle index out of bounds: " + to_string(index) + " Answer array size: " + to_string(this->handles_size)); + Utils::error("Handle index out of bounds: " + to_string(index) + + " Answer array size: " + to_string(this->handles_size)); } return handles[index]; } -unsigned int RedisSet::size() { - return this->handles_size; -} +unsigned int RedisSet::size() { return this->handles_size; } -RedisStringBundle::RedisStringBundle(redisReply *reply) : HandleList() { +RedisStringBundle::RedisStringBundle(redisReply* reply) : HandleList() { unsigned int handle_length = (HANDLE_HASH_SIZE - 1); this->redis_reply = reply; this->handles_size = reply->len / handle_length; - this->handles = new char *[this->handles_size]; + this->handles = new char*[this->handles_size]; for (unsigned int i = 0; i < this->handles_size; i++) { handles[i] = strndup(reply->str + (i * handle_length), handle_length); } @@ -47,46 +47,51 @@ RedisStringBundle::~RedisStringBundle() { for (unsigned int i = 0; i < this->handles_size; i++) { free(this->handles[i]); } - delete [] this->handles; + delete[] this->handles; freeReplyObject(this->redis_reply); } -const char *RedisStringBundle::get_handle(unsigned int index) { +const char* RedisStringBundle::get_handle(unsigned int index) { if (index > this->handles_size) { - Utils::error("Handle index out of bounds: " + to_string(index) + " Answer handles size: " + to_string(this->handles_size)); + Utils::error("Handle index out of bounds: " + to_string(index) + + " Answer handles size: " + to_string(this->handles_size)); } return handles[index]; } -unsigned int RedisStringBundle::size() { - return this->handles_size; -} +unsigned int RedisStringBundle::size() { return this->handles_size; } MongodbDocument::MongodbDocument(core::v1::optional& document) { this->document = document; } -MongodbDocument::~MongodbDocument() { -} +MongodbDocument::~MongodbDocument() {} -const char *MongodbDocument::get(const string &key) { - // Note for reference: .to_string() instead of .data() would return a std::string +const char* MongodbDocument::get(const string& key) { + // Note for reference: .to_string() instead of .data() would return a + // std::string return ((*this->document)[key]).get_string().value.data(); } -const char *MongodbDocument::get(const string &array_key, unsigned int index) { - // Note for reference: .to_string() instead of .data() would return a std::string +const char* MongodbDocument::get(const string& array_key, unsigned int index) { + // Note for reference: .to_string() instead of .data() would return a + // std::string return ((*this->document)[array_key]).get_array().value[index].get_string().value.data(); } -unsigned int MongodbDocument::get_size(const string &array_key) { - // NOTE TO REVIEWER - // TODO: this implementation is wrong and need to be fixed before integration in das-atom-db - // I couldn't figure out a way to discover the number of elements in a BSON array. - //cout << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << endl; - //cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size()" << endl; - //cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() length: " << ((*this->document)[array_key]).get_array().value.length() << endl; - //cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() HASH: " << HANDLE_HASH_SIZE << endl; - //cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() size: " << ((*this->document)[array_key]).get_array().value.length() / HANDLE_HASH_SIZE << endl; +unsigned int MongodbDocument::get_size(const string& array_key) { + // NOTE TO REVIEWER + // TODO: this implementation is wrong and need to be fixed before integration + // in das-atom-db I couldn't figure out a way to discover the number of + // elements in a BSON array. cout << + // "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + // << endl; cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size()" << endl; + // cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() length: " << + // ((*this->document)[array_key]).get_array().value.length() << endl; cout << + // "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() HASH: " << + // HANDLE_HASH_SIZE << endl; cout << "XXXXXXXXXXXXXXXXXXX + // MongodbDocument::get_size() size: " << + // ((*this->document)[array_key]).get_array().value.length() / + // HANDLE_HASH_SIZE << endl; return ((*this->document)[array_key]).get_array().value.length() / HANDLE_HASH_SIZE; } diff --git a/src/query_engine/AtomDBAPITypes.h b/src/query_engine/AtomDBAPITypes.h index 3679508..0dd1a99 100644 --- a/src/query_engine/AtomDBAPITypes.h +++ b/src/query_engine/AtomDBAPITypes.h @@ -2,12 +2,14 @@ #define _QUERY_ENGINE_ATOMDBAPITYPES_H #include + #include #include #include #include #include #include + #include "Utils.h" using namespace std; @@ -16,97 +18,85 @@ using namespace commons; namespace query_engine { namespace atomdb_api_types { - // ------------------------------------------------------------------------------------------------- // NOTE TO REVIEWER: // -// This class will be replaced/integrated by/with classes already implemented in das-atom-db. +// This class will be replaced/integrated by/with classes already implemented in +// das-atom-db. // -// However, that classes will need to be revisited in order to allow the methods implemented here -// because although the design of such methods is nasty, they have the string advantage of -// allowing the reuse of structures allocated by the DBMS (Redis an MongoDB) withpout the need -// of re-allocation of other dataclasses. Although this nasty behavior may not be desirable -// outside the DAS bounds, it's quite appealing inside the query engine (and perhaps other +// However, that classes will need to be revisited in order to allow the methods +// implemented here because although the design of such methods is nasty, they +// have the string advantage of allowing the reuse of structures allocated by +// the DBMS (Redis an MongoDB) withpout the need of re-allocation of other +// dataclasses. Although this nasty behavior may not be desirable outside the +// DAS bounds, it's quite appealing inside the query engine (and perhaps other // parts of internal stuff). // -// I think it's pointless to make any further documentation while we don't make this integrfation. +// I think it's pointless to make any further documentation while we don't make +// this integrfation. // ------------------------------------------------------------------------------------------------- - class HandleList { - -public: - + public: HandleList() {} virtual ~HandleList() {} - virtual const char *get_handle(unsigned int index) = 0; + virtual const char* get_handle(unsigned int index) = 0; virtual unsigned int size() = 0; }; class RedisSet : public HandleList { - -public: - - RedisSet(redisReply *reply); + public: + RedisSet(redisReply* reply); ~RedisSet(); - const char *get_handle(unsigned int index); + const char* get_handle(unsigned int index); unsigned int size(); -private: - + private: unsigned int handles_size; - char **handles; - redisReply *redis_reply; + char** handles; + redisReply* redis_reply; }; class RedisStringBundle : public HandleList { - -public: - - RedisStringBundle(redisReply *reply); + public: + RedisStringBundle(redisReply* reply); ~RedisStringBundle(); - const char *get_handle(unsigned int index); + const char* get_handle(unsigned int index); unsigned int size(); -private: - + private: unsigned int handles_size; - char **handles; - redisReply *redis_reply; + char** handles; + redisReply* redis_reply; }; class AtomDocument { - -public: - + public: AtomDocument() {} virtual ~AtomDocument() {} - virtual const char *get(const string &key) = 0; - virtual const char *get(const string &array_key, unsigned int index) = 0; - virtual unsigned int get_size(const string &array_key) = 0; + virtual const char* get(const string& key) = 0; + virtual const char* get(const string& array_key, unsigned int index) = 0; + virtual unsigned int get_size(const string& array_key) = 0; }; class MongodbDocument : public AtomDocument { - -public: - + public: MongodbDocument(core::v1::optional& document); ~MongodbDocument(); - const char *get(const string &key); - virtual const char *get(const string &array_key, unsigned int index); - virtual unsigned int get_size(const string &array_key); - -private: + const char* get(const string& key); + virtual const char* get(const string& array_key, unsigned int index); + virtual unsigned int get_size(const string& array_key); + private: core::v1::optional document; }; -} // namespace atomdb_api_types -} // namespace query_engine +} // namespace atomdb_api_types +} // namespace query_engine -#endif // _QUERY_ENGINE_ATOMDBAPITYPES_H +#endif // _QUERY_ENGINE_ATOMDBAPITYPES_H diff --git a/src/query_engine/AtomDBSingleton.cc b/src/query_engine/AtomDBSingleton.cc index a037923..4ec0711 100644 --- a/src/query_engine/AtomDBSingleton.cc +++ b/src/query_engine/AtomDBSingleton.cc @@ -1,4 +1,5 @@ #include "AtomDBSingleton.h" + #include "Utils.h" using namespace query_engine; @@ -12,7 +13,9 @@ shared_ptr AtomDBSingleton::atom_db = shared_ptr{}; void AtomDBSingleton::init() { if (initialized) { - Utils::error("AtomDBSingleton already initialized. AtomDBSingleton::init() should be called only once."); + Utils::error( + "AtomDBSingleton already initialized. AtomDBSingleton::init() " + "should be called only once."); } else { AtomDB::initialize_statics(); atom_db = shared_ptr(new AtomDB()); @@ -21,9 +24,12 @@ void AtomDBSingleton::init() { } shared_ptr AtomDBSingleton::get_instance() { - if (! initialized) { - Utils::error("Uninitialized AtomDBSingleton. AtomDBSingleton::init() must be called before AtomDBSingleton::get_instance()"); - return shared_ptr{}; // To avoid warnings + if (!initialized) { + Utils::error( + "Uninitialized AtomDBSingleton. AtomDBSingleton::init() must " + "be called before " + "AtomDBSingleton::get_instance()"); + return shared_ptr{}; // To avoid warnings } else { return atom_db; } diff --git a/src/query_engine/AtomDBSingleton.h b/src/query_engine/AtomDBSingleton.h index 55e4010..52fd743 100644 --- a/src/query_engine/AtomDBSingleton.h +++ b/src/query_engine/AtomDBSingleton.h @@ -2,6 +2,7 @@ #define _QUERY_ENGINE_ATOMDBSINGLETON_H #include + #include "AtomDB.h" using namespace std; @@ -11,26 +12,25 @@ namespace query_engine { // ------------------------------------------------------------------------------------------------- // NOTE TO REVIEWER: // -// This class will be replaced/integrated by/with classes already implemented in das-atom-db. +// This class will be replaced/integrated by/with classes already implemented in +// das-atom-db. // -// I think it's pointless to make any further documentation while we don't make this integrfation. +// I think it's pointless to make any further documentation while we don't make +// this integrfation. // ------------------------------------------------------------------------------------------------- class AtomDBSingleton { - -public: - + public: ~AtomDBSingleton() {} static void init(); static shared_ptr get_instance(); -private: - + private: AtomDBSingleton() {} static bool initialized; static shared_ptr atom_db; }; -} // namespace query_engine +} // namespace query_engine -#endif // _QUERY_ENGINE_ATOMDBSINGLETON_H +#endif // _QUERY_ENGINE_ATOMDBSINGLETON_H diff --git a/src/query_engine/CountAnswer.h b/src/query_engine/CountAnswer.h index 7ae8a44..a7ae909 100644 --- a/src/query_engine/CountAnswer.h +++ b/src/query_engine/CountAnswer.h @@ -13,11 +13,11 @@ namespace query_engine { class CountAnswer : public QueryAnswer { public: - CountAnswer(int count) : count(count) {}; + CountAnswer(int count) : count(count){}; - CountAnswer() : count(UNDEFINED_COUNT) {}; + CountAnswer() : count(UNDEFINED_COUNT){}; - ~CountAnswer() {}; + ~CountAnswer(){}; const string& tokenize() override { this->token_representation = std::to_string(this->count); diff --git a/src/query_engine/DASNode.cc b/src/query_engine/DASNode.cc index c77ca6a..cb1aad3 100644 --- a/src/query_engine/DASNode.cc +++ b/src/query_engine/DASNode.cc @@ -149,7 +149,8 @@ QueryElement* PatternMatchingQuery::build_link_template(vector& tokens, unsigned int arity = std::stoi(tokens[cursor + 2]); if (element_stack.size() < arity) { Utils::error( - "PatternMatchingQuery message: parse error in tokens - too few arguments for LINK_TEMPLATE"); + "PatternMatchingQuery message: parse error in tokens - too " + "few arguments for LINK_TEMPLATE"); } switch (arity) { // TODO: consider replacing each "case" below by a pre-processor macro call @@ -234,7 +235,9 @@ QueryElement* PatternMatchingQuery::build_link_template(vector& tokens, return new LinkTemplate<10>(tokens[cursor + 1], targets, this->context); } default: { - Utils::error("PatternMatchingQuery message: max supported arity for LINK_TEMPLATE: 10"); + Utils::error( + "PatternMatchingQuery message: max supported arity for " + "LINK_TEMPLATE: 10"); } } return NULL; // Just to avoid warnings. This is not actually reachable. @@ -245,7 +248,9 @@ QueryElement* PatternMatchingQuery::build_and(vector& tokens, stack& element_stack) { unsigned int num_clauses = std::stoi(tokens[cursor + 1]); if (element_stack.size() < num_clauses) { - Utils::error("PatternMatchingQuery message: parse error in tokens - too few arguments for AND"); + Utils::error( + "PatternMatchingQuery message: parse error in tokens - too " + "few arguments for AND"); } switch (num_clauses) { // TODO: consider replacing each "case" below by a pre-processor macro call @@ -341,7 +346,9 @@ QueryElement* PatternMatchingQuery::build_or(vector& tokens, stack& element_stack) { unsigned int num_clauses = std::stoi(tokens[cursor + 1]); if (element_stack.size() < num_clauses) { - Utils::error("PatternMatchingQuery message: parse error in tokens - too few arguments for OR"); + Utils::error( + "PatternMatchingQuery message: parse error in tokens - too " + "few arguments for OR"); } switch (num_clauses) { // TODO: consider replacing each "case" below by a pre-processor macro call @@ -437,7 +444,9 @@ QueryElement* PatternMatchingQuery::build_link(vector& tokens, stack& element_stack) { unsigned int arity = std::stoi(tokens[cursor + 2]); if (element_stack.size() < arity) { - Utils::error("PatternMatchingQuery message: parse error in tokens - too few arguments for LINK"); + Utils::error( + "PatternMatchingQuery message: parse error in tokens - too " + "few arguments for LINK"); } switch (arity) { // TODO: consider replacing each "case" below by a pre-processor macro call @@ -578,7 +587,9 @@ PatternMatchingQuery::PatternMatchingQuery(string command, vector& token } if (element_stack.size() != 1) { - Utils::error("PatternMatchingQuery message: parse error in tokens (trailing elements)"); + Utils::error( + "PatternMatchingQuery message: parse error in tokens " + "(trailing elements)"); } this->root_query_element = element_stack.top(); element_stack.pop(); diff --git a/src/query_engine/HandlesAnswer.cc b/src/query_engine/HandlesAnswer.cc index a2a78f6..d3cb93a 100644 --- a/src/query_engine/HandlesAnswer.cc +++ b/src/query_engine/HandlesAnswer.cc @@ -1,23 +1,22 @@ #include "HandlesAnswer.h" -#include "Utils.h" + #include #include #include +#include "Utils.h" + using namespace query_engine; using namespace commons; // ------------------------------------------------------------------------------------------------- // Assignment -Assignment::Assignment() { - this->size = 0; -} +Assignment::Assignment() { this->size = 0; } -Assignment::~Assignment() { -} +Assignment::~Assignment() {} -bool Assignment::assign(const char *label, const char *value) { +bool Assignment::assign(const char* label, const char* value) { for (unsigned int i = 0; i < this->size; i++) { // if label is already present, return true iff its value is the same if (strncmp(label, this->labels[i], MAX_VARIABLE_NAME_SIZE) == 0) { @@ -30,32 +29,33 @@ bool Assignment::assign(const char *label, const char *value) { this->size++; if (this->size == MAX_NUMBER_OF_VARIABLES_IN_QUERY) { Utils::error( - "Assignment size exceeds the maximal number of allowed variables in a query: " + + "Assignment size exceeds the maximal number of allowed " + "variables in a query: " + std::to_string(MAX_NUMBER_OF_VARIABLES_IN_QUERY)); } return true; } -bool Assignment::is_compatible(const Assignment &other) { +bool Assignment::is_compatible(const Assignment& other) { for (unsigned int i = 0; i < this->size; i++) { for (unsigned int j = 0; j < other.size; j++) { if ((strncmp(this->labels[i], other.labels[j], MAX_VARIABLE_NAME_SIZE) == 0) && (strncmp(this->values[i], other.values[j], HANDLE_HASH_SIZE) != 0)) { - return false; + return false; } } } return true; } -void Assignment::copy_from(const Assignment &other) { +void Assignment::copy_from(const Assignment& other) { this->size = other.size; - unsigned int num_bytes = this->size * sizeof(char *); - memcpy((void *) this->labels, (const void *) other.labels, num_bytes); - memcpy((void *) this->values, (const void *) other.values, num_bytes); + unsigned int num_bytes = this->size * sizeof(char*); + memcpy((void*) this->labels, (const void*) other.labels, num_bytes); + memcpy((void*) this->values, (const void*) other.values, num_bytes); } -void Assignment::add_assignments(const Assignment &other) { +void Assignment::add_assignments(const Assignment& other) { bool already_contains; for (unsigned int j = 0; j < other.size; j++) { already_contains = false; @@ -65,7 +65,7 @@ void Assignment::add_assignments(const Assignment &other) { break; } } - if (! already_contains) { + if (!already_contains) { this->labels[this->size] = other.labels[j]; this->values[this->size] = other.values[j]; this->size++; @@ -73,7 +73,7 @@ void Assignment::add_assignments(const Assignment &other) { } } -const char *Assignment::get(const char *label) { +const char* Assignment::get(const char* label) { for (unsigned int i = 0; i < this->size; i++) { if (strncmp(label, this->labels[i], MAX_VARIABLE_NAME_SIZE) == 0) { return this->values[i]; @@ -82,9 +82,7 @@ const char *Assignment::get(const char *label) { return NULL; } -unsigned int Assignment::variable_count() { - return this->size; -} +unsigned int Assignment::variable_count() { return this->size; } string Assignment::to_string() { string answer = "{"; @@ -101,40 +99,32 @@ string Assignment::to_string() { // ------------------------------------------------------------------------------------------------- // HandlesAnswer - -HandlesAnswer::HandlesAnswer() : HandlesAnswer(0.0) { -} +HandlesAnswer::HandlesAnswer() : HandlesAnswer(0.0) {} HandlesAnswer::HandlesAnswer(double importance) { this->importance = importance; this->handles_size = 0; } -HandlesAnswer::HandlesAnswer(const char *handle, double importance) { +HandlesAnswer::HandlesAnswer(const char* handle, double importance) { this->importance = importance; this->handles[0] = handle; this->handles_size = 1; } -HandlesAnswer::~HandlesAnswer() { -} +HandlesAnswer::~HandlesAnswer() {} -void HandlesAnswer::add_handle(const char *handle) { - this->handles[this->handles_size++] = handle; -} +void HandlesAnswer::add_handle(const char* handle) { this->handles[this->handles_size++] = handle; } -HandlesAnswer *HandlesAnswer::copy(HandlesAnswer *base) { // Static method - HandlesAnswer *copy = new HandlesAnswer(base->importance); +HandlesAnswer* HandlesAnswer::copy(HandlesAnswer* base) { // Static method + HandlesAnswer* copy = new HandlesAnswer(base->importance); copy->assignment.copy_from(base->assignment); copy->handles_size = base->handles_size; - memcpy( - (void *) copy->handles, - (const void *) base->handles, - base->handles_size * sizeof(char *)); + memcpy((void*) copy->handles, (const void*) base->handles, base->handles_size * sizeof(char*)); return copy; } -bool HandlesAnswer::merge(HandlesAnswer *other, bool merge_handles) { +bool HandlesAnswer::merge(HandlesAnswer* other, bool merge_handles) { if (this->assignment.is_compatible(other->assignment)) { this->assignment.add_assignments(other->assignment); bool already_exist; @@ -148,7 +138,7 @@ bool HandlesAnswer::merge(HandlesAnswer *other, bool merge_handles) { break; } } - if (! already_exist) { + if (!already_exist) { this->handles[this->handles_size++] = other->handles[j]; } } @@ -169,21 +159,21 @@ string HandlesAnswer::to_string() { } } answer += "] " + this->assignment.to_string() + " " + std::to_string(this->importance); - //answer += "] " + this->assignment.to_string(); + // answer += "] " + this->assignment.to_string(); return answer; } -const string &HandlesAnswer::tokenize() { - // char_count is computed to be slightly larger than actually required by assuming - // e.g. 3 digits to represent sizes +const string& HandlesAnswer::tokenize() { + // char_count is computed to be slightly larger than actually required by + // assuming e.g. 3 digits to represent sizes char importance_buffer[13]; sprintf(importance_buffer, "%.10f", this->importance); - unsigned int char_count = - 13 // importance with 10 decimals + space - + 4 // (up to 3 digits) to represent this->handles_size + space - + this->handles_size * (HANDLE_HASH_SIZE + 1) // handles + spaces - + 4 // (up to 3 digits) to represent this->assignment.size + space - + this->assignment.size * (MAX_VARIABLE_NAME_SIZE + HANDLE_HASH_SIZE + 2); // labelhandle + unsigned int char_count = 13 // importance with 10 decimals + space + + 4 // (up to 3 digits) to represent this->handles_size + space + + this->handles_size * (HANDLE_HASH_SIZE + 1) // handles + spaces + + 4 // (up to 3 digits) to represent this->assignment.size + space + + this->assignment.size * (MAX_VARIABLE_NAME_SIZE + HANDLE_HASH_SIZE + + 2); // labelhandle this->token_representation.clear(); this->token_representation.reserve(char_count); @@ -208,12 +198,10 @@ const string &HandlesAnswer::tokenize() { return this->token_representation; } -static inline void read_token( - const char *token_string, - unsigned int &cursor, - char *token, - unsigned int token_size) { - +static inline void read_token(const char* token_string, + unsigned int& cursor, + char* token, + unsigned int token_size) { unsigned int cursor_token = 0; while (token_string[cursor] != ' ') { if ((cursor_token == token_size) || (token_string[cursor] == '\0')) { @@ -225,9 +213,8 @@ static inline void read_token( cursor++; } -void HandlesAnswer::untokenize(const string &tokens) { - - const char *token_string = tokens.c_str(); +void HandlesAnswer::untokenize(const string& tokens) { + const char* token_string = tokens.c_str(); char number[4]; char importance[13]; char handle[HANDLE_HASH_SIZE]; @@ -241,7 +228,8 @@ void HandlesAnswer::untokenize(const string &tokens) { read_token(token_string, cursor, number, 4); this->handles_size = (unsigned int) std::stoi(number); if (this->handles_size > MAX_NUMBER_OF_OPERATION_CLAUSES) { - Utils::error("Invalid handles_size: " + std::to_string(this->handles_size) + " untokenizing HandlesAnswer"); + Utils::error("Invalid handles_size: " + std::to_string(this->handles_size) + + " untokenizing HandlesAnswer"); } for (unsigned int i = 0; i < this->handles_size; i++) { @@ -253,7 +241,8 @@ void HandlesAnswer::untokenize(const string &tokens) { this->assignment.size = (unsigned int) std::stoi(number); if (this->assignment.size > MAX_NUMBER_OF_VARIABLES_IN_QUERY) { - Utils::error("Invalid number of assignments: " + std::to_string(this->assignment.size) + " untokenizing HandlesAnswer"); + Utils::error("Invalid number of assignments: " + std::to_string(this->assignment.size) + + " untokenizing HandlesAnswer"); } for (unsigned int i = 0; i < this->assignment.size; i++) { diff --git a/src/query_engine/HandlesAnswer.h b/src/query_engine/HandlesAnswer.h index 2fb0534..c81a3be 100644 --- a/src/query_engine/HandlesAnswer.h +++ b/src/query_engine/HandlesAnswer.h @@ -2,16 +2,18 @@ #define _QUERY_ENGINE_HANDLESANSWER_H #include -#include "expression_hasher.h" + #include "QueryAnswer.h" +#include "expression_hasher.h" using namespace std; namespace query_engine { /** - * This class is the representation of a set of variable assignments. It's a set because each - * variable can be assigned to exactly one value and the order of assignments is irrelevant. + * This class is the representation of a set of variable assignments. It's a set + * because each variable can be assigned to exactly one value and the order of + * assignments is irrelevant. * * "label1" -> "value1" * "label2" -> "value2" @@ -19,116 +21,120 @@ namespace query_engine { * "labelN" -> "valueN" */ class Assignment { - friend class HandlesAnswer; - public: - - /** - * Basic constructor. - */ - Assignment(); - - /** - * Destructor. - */ - ~Assignment(); - - /** - * Assign a value to a label. - * - * If the label have already an assigned value, assign() will check if the value is the - * same. If not, nothing is done and false is returned. If the value is the same, or - * if the label haven't been assigned yet, true is returned. - * - * @param label Label - * @param value Value to be assigned to the passed label. - * @return true iff the label have no value assigned to it or if the passed value is - * the same as the currently assigned value. - */ - bool assign(const char *label, const char *value); - - /** - * Returns the value assigned to a given label or NULL if no value is assigned to it. - * - * @param label Label to be search for. - * @return The value assigned to a given label or NULL if no value is assigned to it. - */ - const char *get(const char *label); - - /** - * Returns true if the passed Assignment is compatible with this one or false otherwise. - * - * For two Assignments to be considered compatible, all the labels they share must be - * assigned to the same value. Labels defined in only one of the Assignments aren't - * taken into account (so assignments with no common labels will always be compatible). - * - * Empty Assignments are compatible with any other Assignment. - */ - bool is_compatible(const Assignment &other); - - /** - * Shallow copy operation. No allocation of labels or values are performed. - * - * @param other Assignment to be copied from. - */ - void copy_from(const Assignment &other); - - /** - * Adds assignments from other Assignment by making a shallow copy of labels and values. - * - * Labels present in both Assignments are disregarded. So, for instance, if 'this' has: - * - * "label1"-> "value1" - * "label2"-> "value2" - * "label3"-> "value3" - * - * and 'other' has: - * - * "label1"-> "valueX" - * "label2"-> "value2" - * "label4"-> "value4" - * - * The result in 'this' after add_assignment() would be: - * - * "label1"-> "value1" - * "label2"-> "value2" - * "label3"-> "value3" - * "label4"-> "value4" - */ - void add_assignments(const Assignment &other); - - /** - * Returns the number of labels in this assignment. - * - * @return The number of labels in this assignment. - */ - unsigned int variable_count(); - - /** - * Returns a string representation of this Node (mainly for debugging; not optimized to - * production environment). - */ - string to_string(); - - private: - - const char *labels[MAX_NUMBER_OF_VARIABLES_IN_QUERY]; - const char *values[MAX_NUMBER_OF_VARIABLES_IN_QUERY]; - unsigned int size; + public: + /** + * Basic constructor. + */ + Assignment(); + + /** + * Destructor. + */ + ~Assignment(); + + /** + * Assign a value to a label. + * + * If the label have already an assigned value, assign() will check if the + * value is the same. If not, nothing is done and false is returned. If the + * value is the same, or if the label haven't been assigned yet, true is + * returned. + * + * @param label Label + * @param value Value to be assigned to the passed label. + * @return true iff the label have no value assigned to it or if the passed + * value is the same as the currently assigned value. + */ + bool assign(const char* label, const char* value); + + /** + * Returns the value assigned to a given label or NULL if no value is assigned + * to it. + * + * @param label Label to be search for. + * @return The value assigned to a given label or NULL if no value is assigned + * to it. + */ + const char* get(const char* label); + + /** + * Returns true if the passed Assignment is compatible with this one or false + * otherwise. + * + * For two Assignments to be considered compatible, all the labels they share + * must be assigned to the same value. Labels defined in only one of the + * Assignments aren't taken into account (so assignments with no common labels + * will always be compatible). + * + * Empty Assignments are compatible with any other Assignment. + */ + bool is_compatible(const Assignment& other); + + /** + * Shallow copy operation. No allocation of labels or values are performed. + * + * @param other Assignment to be copied from. + */ + void copy_from(const Assignment& other); + + /** + * Adds assignments from other Assignment by making a shallow copy of labels + * and values. + * + * Labels present in both Assignments are disregarded. So, for instance, if + * 'this' has: + * + * "label1"-> "value1" + * "label2"-> "value2" + * "label3"-> "value3" + * + * and 'other' has: + * + * "label1"-> "valueX" + * "label2"-> "value2" + * "label4"-> "value4" + * + * The result in 'this' after add_assignment() would be: + * + * "label1"-> "value1" + * "label2"-> "value2" + * "label3"-> "value3" + * "label4"-> "value4" + */ + void add_assignments(const Assignment& other); + + /** + * Returns the number of labels in this assignment. + * + * @return The number of labels in this assignment. + */ + unsigned int variable_count(); + + /** + * Returns a string representation of this Node (mainly for debugging; not + * optimized to production environment). + */ + string to_string(); + + private: + const char* labels[MAX_NUMBER_OF_VARIABLES_IN_QUERY]; + const char* values[MAX_NUMBER_OF_VARIABLES_IN_QUERY]; + unsigned int size; }; /** - * This is a candidate answer for a query. + * This is a candidate answer for a query. * - * Objects of this class are moved through the flow of answers in the query tree. - * They have a set of handles, an Assignment and an attached importance value which - * is calculated using the importance of the elements which have been operated to - * make the answer. + * Objects of this class are moved through the flow of answers in the query + * tree. They have a set of handles, an Assignment and an attached importance + * value which is calculated using the importance of the elements which have + * been operated to make the answer. * - * The set of handles represents Links that, together, represent a candidate answer - * to the query, under the constraints of the attached assignment of variables. For instance, - * suppose we have a query like: + * The set of handles represents Links that, together, represent a candidate + * answer to the query, under the constraints of the attached assignment of + * variables. For instance, suppose we have a query like: * * AND * Inheritance @@ -147,13 +153,11 @@ class Assignment { * $v1 -> S */ class HandlesAnswer : public QueryAnswer { - -public: - + public: /** * Handles which are the constituents of this HandlesAnswer. */ - const char *handles[MAX_NUMBER_OF_OPERATION_CLAUSES]; + const char* handles[MAX_NUMBER_OF_OPERATION_CLAUSES]; /** * Number of handles in this HandlesAnswer. @@ -161,7 +165,8 @@ class HandlesAnswer : public QueryAnswer { unsigned int handles_size; /** - * Estimated importance of this HandlesAnswer based on the importance of its constituents. + * Estimated importance of this HandlesAnswer based on the importance of its + * constituents. */ double importance; @@ -176,7 +181,7 @@ class HandlesAnswer : public QueryAnswer { * @param handle First handle in this HandlesAnswer. * @param importance Estimated importance of this HandlesAnswer. */ - HandlesAnswer(const char *handle, double importance); + HandlesAnswer(const char* handle, double importance); /** * Constructor. @@ -200,63 +205,66 @@ class HandlesAnswer : public QueryAnswer { * * @param handles Handle to be added to this HandlesAnswer. */ - void add_handle(const char *handle); + void add_handle(const char* handle); /** * Merges this HandlesAnswer with the passed one. * * @param other HandlesAnswer to be merged in this one. - * @param merge_handles A flag (defaulted to true) to indicate whether the handles should be - * merged (in addition to the assignments). + * @param merge_handles A flag (defaulted to true) to indicate whether the + * handles should be merged (in addition to the assignments). */ - bool merge(HandlesAnswer *other, bool merge_handles = true); + bool merge(HandlesAnswer* other, bool merge_handles = true); /** * Make a shallow copy of the passed HandlesAnswer. * - * A new HandlesAnswer object is allocated but the assignment and the handles are shallow-copied. + * A new HandlesAnswer object is allocated but the assignment and the handles + * are shallow-copied. */ - static HandlesAnswer *copy(HandlesAnswer *base); + static HandlesAnswer* copy(HandlesAnswer* base); /** - * Tokenizes the HandlesAnswer in a single std::string object (tokens separated by spaces). + * Tokenizes the HandlesAnswer in a single std::string object (tokens + * separated by spaces). * * The tokenized string looks like this: * * N H1 H2 ... HN M L1 V1 L2 V2 ... LM VM * - * N is the number of handles in the HandlesAnswer and M is the number of assignments. Hi are the - * handles and Li Vi are the assignments Li -> Vi + * N is the number of handles in the HandlesAnswer and M is the number of + * assignments. Hi are the handles and Li Vi are the assignments Li -> Vi * - * @return A std::string with tokens separated by spaces which can be used to rebuild this HandlesAnswer. + * @return A std::string with tokens separated by spaces which can be used to + * rebuild this HandlesAnswer. */ const string& tokenize() override; /** - * Rebuild a HandlesAnswer baesd in a list of tokens given in a std::string with tokens separated by spaces. + * Rebuild a HandlesAnswer baesd in a list of tokens given in a std::string + * with tokens separated by spaces. * * The tokenized string looks like this: * * N H1 H2 ... HN M L1 V1 L2 V2 ... LM VM * - * N is the number of handles in the HandlesAnswer and M is the number of assignments. Hi are the - * handles and Li Vi are the assignments Li -> Vi + * N is the number of handles in the HandlesAnswer and M is the number of + * assignments. Hi are the handles and Li Vi are the assignments Li -> Vi * * @param tokens A std::string with the list of tokens separated by spaces. */ - void untokenize(const string &tokens) override; + void untokenize(const string& tokens) override; /** - * Returns a string representation of this Variable (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Variable (mainly for debugging; not + * optimized to production environment). */ string to_string() override; -private: - + private: string token_representation; }; -} // namespace query_engine +} // namespace query_engine -#endif // _QUERY_ENGINE_HANDLESANSWER_H +#endif // _QUERY_ENGINE_HANDLESANSWER_H diff --git a/src/query_engine/StarNode.cc b/src/query_engine/StarNode.cc index 0dc3d18..e56f645 100644 --- a/src/query_engine/StarNode.cc +++ b/src/query_engine/StarNode.cc @@ -1,4 +1,5 @@ #include "StarNode.h" + #include "LeadershipBroker.h" #include "MessageBroker.h" @@ -8,34 +9,26 @@ using namespace std; // ------------------------------------------------------------------------------------------------- // Constructors and destructors -StarNode::StarNode( - const string &node_id, - MessageBrokerType messaging_backend) : - DistributedAlgorithmNode(node_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_backend) { - +StarNode::StarNode(const string& node_id, MessageBrokerType messaging_backend) + : DistributedAlgorithmNode(node_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_backend) { this->is_server = true; this->join_network(); } -StarNode::StarNode( - const string &node_id, - const string &server_id, - MessageBrokerType messaging_backend) : - DistributedAlgorithmNode(node_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_backend) { - +StarNode::StarNode(const string& node_id, const string& server_id, MessageBrokerType messaging_backend) + : DistributedAlgorithmNode(node_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_backend) { this->server_id = server_id; this->is_server = false; this->add_peer(server_id); this->join_network(); } -StarNode::~StarNode() { -} +StarNode::~StarNode() {} // ------------------------------------------------------------------------------------------------- // DistributedAlgorithmNode virtual API -void StarNode::node_joined_network(const string &node_id) { +void StarNode::node_joined_network(const string& node_id) { if (this->is_server) { this->add_peer(node_id); } diff --git a/src/query_engine/StarNode.h b/src/query_engine/StarNode.h index b43ac2d..8fae35e 100644 --- a/src/query_engine/StarNode.h +++ b/src/query_engine/StarNode.h @@ -2,6 +2,7 @@ #define _QUERY_NODE_STARNODE_H #include + #include "DistributedAlgorithmNode.h" using namespace std; @@ -9,15 +10,13 @@ using namespace std; namespace distributed_algorithm_node { /** - * Node in a "star" topology with one single server (which knows every other nodes in the network) - * and N nodes (which know only the server). + * Node in a "star" topology with one single server (which knows every other + * nodes in the network) and N nodes (which know only the server). * * Use the different constructors to choose from client or server. */ class StarNode : public DistributedAlgorithmNode { - -public: - + public: // -------------------------------------------------------------------------------------------- // Constructors and destructors @@ -25,25 +24,22 @@ class StarNode : public DistributedAlgorithmNode { * Server constructor. * * @param node_id ID of this node in the network. - * @param messaging_backend Type of network communication which will be used by the nodes. - * in the network to exchange messages. Defaulted to GRPC. + * @param messaging_backend Type of network communication which will be used + * by the nodes. in the network to exchange messages. Defaulted to GRPC. */ - StarNode( - const string &node_id, - MessageBrokerType messaging_backend = MessageBrokerType::GRPC); + StarNode(const string& node_id, MessageBrokerType messaging_backend = MessageBrokerType::GRPC); /** * Client constructor. * * @param node_id ID of this node in the network. * @param server_id ID of the server node. - * @param messaging_backend Type of network communication which will be used by the nodes - * in the network to exchange messages. Defaulted to GRPC. + * @param messaging_backend Type of network communication which will be used + * by the nodes in the network to exchange messages. Defaulted to GRPC. */ - StarNode( - const string &node_id, - const string &server_id, - MessageBrokerType messaging_backend = MessageBrokerType::GRPC); + StarNode(const string& node_id, + const string& server_id, + MessageBrokerType messaging_backend = MessageBrokerType::GRPC); /** * Destructor @@ -54,26 +50,27 @@ class StarNode : public DistributedAlgorithmNode { // DistributedAlgorithmNode virtual API /** - * Method called when a new node is inserted in the network after this one has already joined. - * Server nodes will keep track of all newly inserted nodes. Client nodes disregard the info. + * Method called when a new node is inserted in the network after this one has + * already joined. Server nodes will keep track of all newly inserted nodes. + * Client nodes disregard the info. * * @param node_id ID of the newly inserted node. */ - void node_joined_network(const string &node_id); + void node_joined_network(const string& node_id); /** * Method called when a leadershipo election is requested. * - * Server nodes votes in themselves for leader while client node votes in their server. + * Server nodes votes in themselves for leader while client node votes in + * their server. */ string cast_leadership_vote(); -protected: - + protected: bool is_server; string server_id; }; -} // namespace distributed_algorithm_node +} // namespace distributed_algorithm_node -#endif // _QUERY_NODE_STARNODE_H +#endif // _QUERY_NODE_STARNODE_H diff --git a/src/query_engine/answer_processor/AttentionBrokerUpdater.h b/src/query_engine/answer_processor/AttentionBrokerUpdater.h index e580a08..bdecfc8 100644 --- a/src/query_engine/answer_processor/AttentionBrokerUpdater.h +++ b/src/query_engine/answer_processor/AttentionBrokerUpdater.h @@ -57,8 +57,8 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { // Protobuf data structures dasproto::HandleList* handle_list; // will contain single_answer (can't be used directly // because it's a list, not a set. - dasproto::HandleCount handle_count; // Counting of how many times each handle appeared - // in all single_entry + dasproto::HandleCount handle_count; // Counting of how many times each + // handle appeared in all single_entry dasproto::Ack* ack; // Command return shared_ptr db = AtomDBSingleton::get_instance(); @@ -88,7 +88,8 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { #ifdef DEBUG count_total_processed++; if ((count_total_processed % 1000) == 0) { - cout << "RemoteSink::attention_broker_postprocess_method() count_total_processed: " + cout << "RemoteSink::attention_broker_postprocess_method() " + "count_total_processed: " << count_total_processed << endl; } #endif @@ -130,8 +131,8 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { single_answer.clear(); ack = new dasproto::Ack(); #ifdef DEBUG - // cout << "RemoteSink::attention_broker_postprocess_method() requesting CORRELATE" << - // endl; + // cout << "RemoteSink::attention_broker_postprocess_method() requesting + // CORRELATE" << endl; #endif stub->correlate(new grpc::ClientContext(), *handle_list, ack); if (ack->msg() != "CORRELATE") { @@ -149,7 +150,8 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { auto stub = dasproto::AttentionBroker::NewStub(grpc::CreateChannel( this->attention_broker_address, grpc::InsecureChannelCredentials())); #ifdef DEBUG - cout << "RemoteSink::attention_broker_postprocess_method() requesting STIMULATE" + cout << "RemoteSink::attention_broker_postprocess_method() " + "requesting STIMULATE" << endl; #endif handle_count.set_context(this->query_context); @@ -177,7 +179,9 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { auto stub = dasproto::AttentionBroker::NewStub( grpc::CreateChannel(this->attention_broker_address, grpc::InsecureChannelCredentials())); #ifdef DEBUG - cout << "RemoteSink::attention_broker_postprocess_method() requesting STIMULATE" << endl; + cout << "RemoteSink::attention_broker_postprocess_method() requesting " + "STIMULATE" + << endl; #endif handle_count.set_context(this->query_context); stub->stimulate(new grpc::ClientContext(), handle_count, ack); diff --git a/src/query_engine/query_element/And.h b/src/query_engine/query_element/And.h index ebc9bc6..5143b51 100644 --- a/src/query_engine/query_element/And.h +++ b/src/query_engine/query_element/And.h @@ -1,53 +1,50 @@ #ifndef _QUERY_ELEMENT_AND_H #define _QUERY_ELEMENT_AND_H -#include #include -#include "Operator.h" +#include + #include "HandlesAnswer.h" +#include "Operator.h" using namespace std; namespace query_element { - /** * QueryElement representing an AND logic operator. * - * And operates on N clauses. Each clause can be either a Source or another Operator. + * And operates on N clauses. Each clause can be either a Source or another + * Operator. */ template class And : public Operator { - -public: - + public: // -------------------------------------------------------------------------------------------- // Constructors and destructors /** * Constructor. * - * @param clauses Array with N clauses (each clause is supposed to be a Source or an Operator). + * @param clauses Array with N clauses (each clause is supposed to be a Source + * or an Operator). */ - And(QueryElement **clauses) : Operator(clauses) { - initialize(clauses); - } + And(QueryElement** clauses) : Operator(clauses) { initialize(clauses); } /** * Constructor. * - * @param clauses Array with N clauses (each clause is supposed to be a Source or an Operator). + * @param clauses Array with N clauses (each clause is supposed to be a Source + * or an Operator). */ - And(const array &clauses) : Operator(clauses) { - initialize((QueryElement **) clauses.data()); + And(const array& clauses) : Operator(clauses) { + initialize((QueryElement**) clauses.data()); } /** * Destructor. */ - ~And() { - graceful_shutdown(); - } + ~And() { graceful_shutdown(); } // -------------------------------------------------------------------------------------------- // QueryElement API @@ -64,43 +61,31 @@ class And : public Operator { this->operator_thread = NULL; } } - + // -------------------------------------------------------------------------------------------- // Private stuff -private: - + private: class CandidateRecord { - public: - HandlesAnswer *answer[N]; + public: + HandlesAnswer* answer[N]; unsigned int index[N]; double fitness; - CandidateRecord() { - } - CandidateRecord(const CandidateRecord &other) { + CandidateRecord() {} + CandidateRecord(const CandidateRecord& other) { this->fitness = other.fitness; - memcpy((void *) this->index, (const void *) other.index, N * sizeof(unsigned int)); - memcpy( - (void *) this->answer, - (const void *) other.answer, - N * sizeof(HandlesAnswer *)); + memcpy((void*) this->index, (const void*) other.index, N * sizeof(unsigned int)); + memcpy((void*) this->answer, (const void*) other.answer, N * sizeof(HandlesAnswer*)); } - CandidateRecord& operator=(const CandidateRecord &other) { + CandidateRecord& operator=(const CandidateRecord& other) { this->fitness = other.fitness; - memcpy((void *) this->index, (const void *) other.index, N * sizeof(unsigned int)); - memcpy( - (void *) this->answer, - (const void *) other.answer, - N * sizeof(HandlesAnswer *)); + memcpy((void*) this->index, (const void*) other.index, N * sizeof(unsigned int)); + memcpy((void*) this->answer, (const void*) other.answer, N * sizeof(HandlesAnswer*)); return *this; } - bool operator<(const CandidateRecord &other) const { - return this->fitness < other.fitness; - } - bool operator>(const CandidateRecord &other) const { - return this->fitness > other.fitness; - } - bool operator==(const CandidateRecord &other) const { + bool operator<(const CandidateRecord& other) const { return this->fitness < other.fitness; } + bool operator>(const CandidateRecord& other) const { return this->fitness > other.fitness; } + bool operator==(const CandidateRecord& other) const { for (unsigned int i = 0; i < N; i++) { if (this->index[i] != other.index[i]) { return false; @@ -120,17 +105,17 @@ class And : public Operator { } return hash; } - }; + }; - vector query_answer[N]; + vector query_answer[N]; unsigned int next_input_to_process[N]; priority_queue border; unordered_set visited; bool all_answers_arrived[N]; bool no_more_answers_to_arrive; - thread *operator_thread; + thread* operator_thread; - void initialize(QueryElement **clauses) { + void initialize(QueryElement** clauses) { this->operator_thread = NULL; for (unsigned int i = 0; i < N; i++) { this->next_input_to_process[i] = 0; @@ -149,7 +134,7 @@ class And : public Operator { bool ready_to_process_candidate() { for (unsigned int i = 0; i < N; i++) { - if ((! this->all_answers_arrived[i]) && + if ((!this->all_answers_arrived[i]) && (this->query_answer[i].size() <= (this->next_input_to_process[i] + 1))) { return false; } @@ -161,17 +146,17 @@ class And : public Operator { if (this->no_more_answers_to_arrive) { return; } - HandlesAnswer *answer; + HandlesAnswer* answer; unsigned int all_arrived_count = 0; bool no_new_answer = true; for (unsigned int i = 0; i < N; i++) { - while ((answer = dynamic_cast(this->input_buffer[i]->pop_query_answer())) != NULL) { + while ((answer = dynamic_cast(this->input_buffer[i]->pop_query_answer())) != + NULL) { no_new_answer = false; this->query_answer[i].push_back(answer); } if (this->input_buffer[i]->is_query_answers_empty() && this->input_buffer[i]->is_query_answers_finished()) { - this->all_answers_arrived[i] = true; all_arrived_count++; } @@ -185,10 +170,10 @@ class And : public Operator { } } - void operate_candidate(const CandidateRecord &candidate) { - HandlesAnswer *new_query_answer = HandlesAnswer::copy(candidate.answer[0]); + void operate_candidate(const CandidateRecord& candidate) { + HandlesAnswer* new_query_answer = HandlesAnswer::copy(candidate.answer[0]); for (unsigned int i = 1; i < N; i++) { - if (! new_query_answer->merge(candidate.answer[i])) { + if (!new_query_answer->merge(candidate.answer[i])) { delete new_query_answer; return; } @@ -209,7 +194,7 @@ class And : public Operator { return true; } - void expand_border(const CandidateRecord &last_used_candidate) { + void expand_border(const CandidateRecord& last_used_candidate) { CandidateRecord candidate; unsigned int index_in_queue; bool abort_candidate; @@ -229,7 +214,7 @@ class And : public Operator { break; } } - candidate.answer[answer_queue_index] = + candidate.answer[answer_queue_index] = this->query_answer[answer_queue_index][index_in_queue]; candidate.index[answer_queue_index] = index_in_queue; candidate.fitness *= candidate.answer[answer_queue_index]->importance; @@ -245,11 +230,8 @@ class And : public Operator { } void and_operator_method() { - do { - if (QueryElement::is_flow_finished() || - this->output_buffer->is_query_answers_finished()) { - + if (QueryElement::is_flow_finished() || this->output_buffer->is_query_answers_finished()) { return; } @@ -258,19 +240,19 @@ class And : public Operator { return; } ingest_newly_arrived_answers(); - } while (! ready_to_process_candidate()); + } while (!ready_to_process_candidate()); if (processed_all_input()) { bool all_finished_flag = true; for (unsigned int i = 0; i < N; i++) { - if (! this->input_buffer[i]->is_query_answers_finished()) { + if (!this->input_buffer[i]->is_query_answers_finished()) { all_finished_flag = false; break; } } - if (all_finished_flag && - ! this->output_buffer->is_query_answers_finished() && - // processed_all_input() is double-checked on purpose to avoid race condition + if (all_finished_flag && !this->output_buffer->is_query_answers_finished() && + // processed_all_input() is double-checked on purpose to avoid race + // condition processed_all_input()) { this->output_buffer->query_answers_finished(); } @@ -299,6 +281,6 @@ class And : public Operator { } }; -} // namespace query_element +} // namespace query_element -#endif // _QUERY_ELEMENT_AND_H +#endif // _QUERY_ELEMENT_AND_H diff --git a/src/query_engine/query_element/Iterator.cc b/src/query_engine/query_element/Iterator.cc index 67f0b60..4b221d0 100644 --- a/src/query_engine/query_element/Iterator.cc +++ b/src/query_engine/query_element/Iterator.cc @@ -7,26 +7,21 @@ using namespace query_element; // ------------------------------------------------------------------------------------------------- // Public methods -template -Iterator::Iterator( - QueryElement *precedent, - bool delete_precedent_on_destructor) : - Sink(precedent, "Iterator(" + precedent->id + ")", delete_precedent_on_destructor) { -} +template +Iterator::Iterator(QueryElement* precedent, bool delete_precedent_on_destructor) + : Sink(precedent, "Iterator(" + precedent->id + ")", delete_precedent_on_destructor) {} -template -Iterator::~Iterator() { -} +template +Iterator::~Iterator() {} -template +template bool Iterator::finished() { // The order of the AND clauses below matters - return ( - this->input_buffer->is_query_answers_finished() && - this->input_buffer->is_query_answers_empty()); + return (this->input_buffer->is_query_answers_finished() && + this->input_buffer->is_query_answers_empty()); } -template -QueryAnswer *Iterator::pop() { - return (QueryAnswer *) this->input_buffer->pop_query_answer(); +template +QueryAnswer* Iterator::pop() { + return (QueryAnswer*) this->input_buffer->pop_query_answer(); } diff --git a/src/query_engine/query_element/Iterator.h b/src/query_engine/query_element/Iterator.h index d29ef57..a96340a 100644 --- a/src/query_engine/query_element/Iterator.h +++ b/src/query_engine/query_element/Iterator.h @@ -1,8 +1,8 @@ #ifndef _QUERY_ELEMENT_ITERATOR_H #define _QUERY_ELEMENT_ITERATOR_H -#include "Sink.h" #include "QueryAnswer.h" +#include "Sink.h" using namespace std; using namespace query_engine; @@ -10,7 +10,8 @@ using namespace query_engine; namespace query_element { /** - * Concrete Sink that provides an iterator API to give access to the query answers. + * Concrete Sink that provides an iterator API to give access to the query + * answers. * * NB This is not a std::iterator as the behavior we'd expect of a std::iterator * doesn't fit well with the asynchronous nature of QueryElement processing. @@ -21,41 +22,42 @@ namespace query_element { */ template class Iterator : public Sink { - -public: - + public: /** - * Constructor expects that the QueryElement below in the tree is already constructed. + * Constructor expects that the QueryElement below in the tree is already + * constructed. */ - Iterator(QueryElement *precedent, bool delete_precedent_on_destructor = false); + Iterator(QueryElement* precedent, bool delete_precedent_on_destructor = false); ~Iterator(); // -------------------------------------------------------------------------------------------- // Public Iterator API /** - * Return true when all query answers has been processed AND all the query answers - * that reached this QueryElement has been pop'ed out using the method pop(). + * Return true when all query answers has been processed AND all the query + * answers that reached this QueryElement has been pop'ed out using the method + * pop(). * - * @return true iff all query answers has been processed AND all the query answers - * that reached this QueryElement has been pop'ed out using the method pop(). + * @return true iff all query answers has been processed AND all the query + * answers that reached this QueryElement has been pop'ed out using the method + * pop(). */ bool finished(); /** * Return the next query answer or NULL if none are currently available. * - * NB a NULL return DOESN'T mean that the query answers are over. It means that there - * are no query answers available now. Because of the asynchronous nature of QueryElement - * processing, more query answers can arrive later. + * NB a NULL return DOESN'T mean that the query answers are over. It means + * that there are no query answers available now. Because of the asynchronous + * nature of QueryElement processing, more query answers can arrive later. * * @return the next query answer or NULL if none are currently available. */ - QueryAnswer *pop(); + QueryAnswer* pop(); }; -} // namespace query_element +} // namespace query_element #include "Iterator.cc" -#endif // _QUERY_ELEMENT_ITERATOR_H +#endif // _QUERY_ELEMENT_ITERATOR_H diff --git a/src/query_engine/query_element/LinkTemplate.h b/src/query_engine/query_element/LinkTemplate.h index f092811..87b65a2 100644 --- a/src/query_engine/query_element/LinkTemplate.h +++ b/src/query_engine/query_element/LinkTemplate.h @@ -28,8 +28,8 @@ using namespace attention_broker_server; namespace query_element { /** - * Concrete Source that searches for a pattern in the AtomDB and feeds the QueryElement up in the - * query tree with the resulting links. + * Concrete Source that searches for a pattern in the AtomDB and feeds the + * QueryElement up in the query tree with the resulting links. * * A pattern is something like: * @@ -37,12 +37,14 @@ namespace query_element { * Human * $v1 * - * In the example, any links of type "Similarity" pointing to Human as the first target would be - * returned. These returned links are then fed into the subsequent QueryElement in the tree. + * In the example, any links of type "Similarity" pointing to Human as the first + * target would be returned. These returned links are then fed into the + * subsequent QueryElement in the tree. * - * LinkTemplate query the AtomDB for the links that match the pattern. In addition to this, it - * attaches values for any variables in the pattern and sorts all the AtomDB answers by importance - * (by querying the AttentionBroker) before following up the links (most important ones first). + * LinkTemplate query the AtomDB for the links that match the pattern. In + * addition to this, it attaches values for any variables in the pattern and + * sorts all the AtomDB answers by importance (by querying the AttentionBroker) + * before following up the links (most important ones first). * * An arbitrary number of nested levels are allowed. For instance: * @@ -70,12 +72,15 @@ class LinkTemplate : public Source { // Constructors and destructors /** - * Constructor expects an array of QueryElements which can be Terminals or nested LinkTemplate. + * Constructor expects an array of QueryElements which can be Terminals or + * nested LinkTemplate. * - * @param type Link type or WILDCARD to indicate that the link type doesn't matter. - * @param targets An array with targets which can each be a Terminal or a nested LinkTemplate. - * @param context An optional string defining the context used by the AttentionBroker to - * consider STI (short term importance). + * @param type Link type or WILDCARD to indicate that the link type doesn't + * matter. + * @param targets An array with targets which can each be a Terminal or a + * nested LinkTemplate. + * @param context An optional string defining the context used by the + * AttentionBroker to consider STI (short term importance). */ LinkTemplate(const string& type, const array& targets, @@ -93,8 +98,9 @@ class LinkTemplate : public Source { this->handle_keys[0] = (wildcard_flag ? (char*) AtomDB::WILDCARD.c_str() : named_type_hash((char*) type.c_str())); for (unsigned int i = 1; i <= ARITY; i++) { - // It's safe to get stored shared_ptr's raw pointer here because handle_keys[] - // is used solely in this scope so it's guaranteed that handle will not be freed. + // It's safe to get stored shared_ptr's raw pointer here because + // handle_keys[] is used solely in this scope so it's guaranteed that + // handle will not be freed. if (targets[i - 1]->is_terminal) { this->handle_keys[i] = ((Terminal*) targets[i - 1])->handle.get(); } else { @@ -106,9 +112,9 @@ class LinkTemplate : public Source { if (!wildcard_flag) { free(this->handle_keys[0]); } - // This is correct. id is not necessarily a handle but an identifier. It just happens - // that we want the string for this identifier to be the same as the string representing - // the handle. + // This is correct. id is not necessarily a handle but an identifier. It + // just happens that we want the string for this identifier to be the same + // as the string representing the handle. this->id = this->handle.get() + std::to_string(LinkTemplate::next_instance_count()); } diff --git a/src/query_engine/query_element/Operator.h b/src/query_engine/query_element/Operator.h index 70ba51f..8090c16 100644 --- a/src/query_engine/query_element/Operator.h +++ b/src/query_engine/query_element/Operator.h @@ -12,14 +12,15 @@ using namespace std; namespace query_element { /** - * Superclass for elements which represent logic operators on LinkTemplate results (e.g. AND, - * OR and NOT). + * Superclass for elements which represent logic operators on LinkTemplate + * results (e.g. AND, OR and NOT). * * Operator adds the required QueryNode elements to connect either with: * - * - one or more QueryElement downstream in the query tree (each of them can be either - * Operator or SOurce). - * - one QueryElement upstream in the query tree which can be another Operator or a Sink. + * - one or more QueryElement downstream in the query tree (each of them can + * be either Operator or SOurce). + * - one QueryElement upstream in the query tree which can be another + * Operator or a Sink. */ template class Operator : public QueryElement { @@ -30,14 +31,16 @@ class Operator : public QueryElement { /** * Constructor. * - * @param clauses Array of QueryElement, each of them a clause in the operation. + * @param clauses Array of QueryElement, each of them a clause in the + * operation. */ Operator(const array& clauses) { initialize((QueryElement**) clauses.data()); } /** * Constructor. * - * @param clauses Array of QueryElement, each of them a clause in the operation. + * @param clauses Array of QueryElement, each of them a clause in the + * operation. */ Operator(QueryElement** clauses) { initialize(clauses); } @@ -50,10 +53,10 @@ class Operator : public QueryElement { // QueryElement API /** - * Sets up buffers for communication between this operator and its upstream and downstream - * QueryElements. Initializes a single QueryNodeClient for the upstream connection and - * N QueryNodeServer elements for the downstream connections, each corresponding to a clause - * in the operation. + * Sets up buffers for communication between this operator and its upstream + * and downstream QueryElements. Initializes a single QueryNodeClient for the + * upstream connection and N QueryNodeServer elements for the downstream + * connections, each corresponding to a clause in the operation. */ virtual void setup_buffers() { if (this->subsequent_id == "") { @@ -74,8 +77,8 @@ class Operator : public QueryElement { } /** - * Gracefully shuts down the QueryNodes attached to the upstream and downstream communication - * in the query tree. + * Gracefully shuts down the QueryNodes attached to the upstream and + * downstream communication in the query tree. */ virtual void graceful_shutdown() { if (is_flow_finished()) { diff --git a/src/query_engine/query_element/Or.h b/src/query_engine/query_element/Or.h index fe78900..ea1a009 100644 --- a/src/query_engine/query_element/Or.h +++ b/src/query_engine/query_element/Or.h @@ -1,53 +1,50 @@ #ifndef _QUERY_ELEMENT_OR_H #define _QUERY_ELEMENT_OR_H -#include #include -#include "Operator.h" +#include + #include "HandlesAnswer.h" +#include "Operator.h" using namespace std; namespace query_element { - /** * QueryElement representing an OR logic operator. * - * Or operates on N clauses. Each clause can be either a Source or another Operator. + * Or operates on N clauses. Each clause can be either a Source or another + * Operator. */ template class Or : public Operator { - -public: - + public: // -------------------------------------------------------------------------------------------- // Constructors and destructors /** * Constructor. * - * @param clauses Array with N clauses (each clause is supposed to be a Source or an Operator). + * @param clauses Array with N clauses (each clause is supposed to be a Source + * or an Operator). */ - Or(QueryElement **clauses) : Operator(clauses) { - initialize(clauses); - } + Or(QueryElement** clauses) : Operator(clauses) { initialize(clauses); } /** * Constructor. * - * @param clauses Array with N clauses (each clause is supposed to be a Source or an Operator). + * @param clauses Array with N clauses (each clause is supposed to be a Source + * or an Operator). */ - Or(const array &clauses) : Operator(clauses) { - initialize((QueryElement **) clauses.data()); + Or(const array& clauses) : Operator(clauses) { + initialize((QueryElement**) clauses.data()); } /** * Destructor. */ - ~Or() { - graceful_shutdown(); - } + ~Or() { graceful_shutdown(); } // -------------------------------------------------------------------------------------------- // QueryElement API @@ -64,19 +61,18 @@ class Or : public Operator { this->operator_thread = NULL; } } - + // -------------------------------------------------------------------------------------------- // Private stuff -private: - - vector query_answer[N]; + private: + vector query_answer[N]; unsigned int next_input_to_process[N]; bool all_answers_arrived[N]; bool no_more_answers_to_arrive; - thread *operator_thread; + thread* operator_thread; - void initialize(QueryElement **clauses) { + void initialize(QueryElement** clauses) { this->operator_thread = NULL; for (unsigned int i = 0; i < N; i++) { this->next_input_to_process[i] = 0; @@ -95,7 +91,7 @@ class Or : public Operator { bool ready_to_process_candidate() { for (unsigned int i = 0; i < N; i++) { - if ((! this->all_answers_arrived[i]) && + if ((!this->all_answers_arrived[i]) && (this->query_answer[i].size() <= (this->next_input_to_process[i] + 1))) { return false; } @@ -107,17 +103,17 @@ class Or : public Operator { if (this->no_more_answers_to_arrive) { return; } - HandlesAnswer *answer; + HandlesAnswer* answer; unsigned int all_arrived_count = 0; bool no_new_answer = true; for (unsigned int i = 0; i < N; i++) { - while ((answer = dynamic_cast(this->input_buffer[i]->pop_query_answer())) != NULL) { + while ((answer = dynamic_cast(this->input_buffer[i]->pop_query_answer())) != + NULL) { no_new_answer = false; this->query_answer[i].push_back(answer); } if (this->input_buffer[i]->is_query_answers_empty() && this->input_buffer[i]->is_query_answers_finished()) { - this->all_answers_arrived[i] = true; all_arrived_count++; } @@ -145,24 +141,22 @@ class Or : public Operator { double best_importance = -1; for (unsigned int i = 0; i < N; i++) { if (this->next_input_to_process[i] < this->query_answer[i].size()) { - if (this->query_answer[i][this->next_input_to_process[i]]->importance > best_importance) { + if (this->query_answer[i][this->next_input_to_process[i]]->importance > + best_importance) { best_importance = this->query_answer[i][this->next_input_to_process[i]]->importance; best_index = i; } } } if (best_importance < 0) { - Utils::error ("Invalid state in OR operation"); + Utils::error("Invalid state in OR operation"); } return best_index; } void or_operator_method() { - do { - if (QueryElement::is_flow_finished() || - this->output_buffer->is_query_answers_finished()) { - + if (QueryElement::is_flow_finished() || this->output_buffer->is_query_answers_finished()) { return; } @@ -171,41 +165,43 @@ class Or : public Operator { return; } ingest_newly_arrived_answers(); - } while (! ready_to_process_candidate()); + } while (!ready_to_process_candidate()); cout << "XXXXXXX 1" << endl; if (processed_all_input()) { - cout << "XXXXXXX 2" << endl; + cout << "XXXXXXX 2" << endl; bool all_finished_flag = true; for (unsigned int i = 0; i < N; i++) { - if (! this->input_buffer[i]->is_query_answers_finished()) { + if (!this->input_buffer[i]->is_query_answers_finished()) { all_finished_flag = false; break; } } - cout << "XXXXXXX 3" << endl; - if (all_finished_flag && - ! this->output_buffer->is_query_answers_finished() && - // processed_all_input() is double-checked on purpose to avoid race condition + cout << "XXXXXXX 3" << endl; + if (all_finished_flag && !this->output_buffer->is_query_answers_finished() && + // processed_all_input() is double-checked on purpose to avoid race + // condition processed_all_input()) { this->output_buffer->query_answers_finished(); } - cout << "XXXXXXX 4" << endl; + cout << "XXXXXXX 4" << endl; Utils::sleep(); continue; } cout << "XXXXXXX 5" << endl; - + unsigned int selected_clause = select_answer(); cout << "XXXXXXX 6" << endl; - HandlesAnswer *selected_query_answer = this->query_answer[selected_clause][this->next_input_to_process[selected_clause]++]; - cout << std::to_string(selected_clause) << ": " << selected_query_answer->to_string() << endl; + HandlesAnswer* selected_query_answer = + this->query_answer[selected_clause][this->next_input_to_process[selected_clause]++]; + cout << std::to_string(selected_clause) << ": " << selected_query_answer->to_string() + << endl; this->output_buffer->add_query_answer(selected_query_answer); cout << "XXXXXXX 7" << endl; } while (true); } }; -} // namespace query_element +} // namespace query_element -#endif // _QUERY_ELEMENT_OR_H +#endif // _QUERY_ELEMENT_OR_H diff --git a/src/query_engine/query_element/QueryElement.cc b/src/query_engine/query_element/QueryElement.cc index af326ac..49d456b 100644 --- a/src/query_engine/query_element/QueryElement.cc +++ b/src/query_engine/query_element/QueryElement.cc @@ -10,8 +10,7 @@ QueryElement::QueryElement() { this->is_terminal = false; } -QueryElement::~QueryElement() { -} +QueryElement::~QueryElement() {} // ------------------------------------------------------------------------------------------------ // Protected methods diff --git a/src/query_engine/query_element/QueryElement.h b/src/query_engine/query_element/QueryElement.h index fc702b3..a9b2325 100644 --- a/src/query_engine/query_element/QueryElement.h +++ b/src/query_engine/query_element/QueryElement.h @@ -1,10 +1,11 @@ #ifndef _QUERY_ELEMENT_QUERYELEMENT_H #define _QUERY_ELEMENT_QUERYELEMENT_H -#include #include -#include "Utils.h" +#include + #include "QueryNode.h" +#include "Utils.h" #define DEBUG @@ -15,43 +16,48 @@ using namespace commons; namespace query_element { /** - * Basic element in the class hierarchy which represents boolean logical expression involving - * nodes, links and patterns. + * Basic element in the class hierarchy which represents boolean logical + * expression involving nodes, links and patterns. * - * Boolean logical expressions are formed by logical operators (AND, OR, NOT) and - * operands (Node, Link and LinkTemplate). Nested expression are allowed. AND and OR may operate - * on any number (> 1) of arguments while NOT takes a single argument. + * Boolean logical expressions are formed by logical operators (AND, OR, NOT) + * and operands (Node, Link and LinkTemplate). Nested expression are allowed. + * AND and OR may operate on any number (> 1) of arguments while NOT takes a + * single argument. * - * Nodes are defined by type+name. Links are defined by type+targets. LinkTemplates are defined - * like Links, where the Link type and any number of targets may be wildcards (actually, wildcards - * are named variables which are unified as the query is executed). LinkTemplates can also be - * nested, i.e., one of the targets of a LinkTemplate can be another LinkTemplate. + * Nodes are defined by type+name. Links are defined by type+targets. + * LinkTemplates are defined like Links, where the Link type and any number of + * targets may be wildcards (actually, wildcards are named variables which are + * unified as the query is executed). LinkTemplates can also be nested, i.e., + * one of the targets of a LinkTemplate can be another LinkTemplate. * - * There's no limit in the number of nesting levels of LinkTemplates or boolean expressions. + * There's no limit in the number of nesting levels of LinkTemplates or boolean + * expressions. * - * A query can be understood as a tree whose nodes are QueryElements. Internal nodes are - * logical operators and leaves are either Links or LinkTemplates (nested or not). + * A query can be understood as a tree whose nodes are QueryElements. Internal + * nodes are logical operators and leaves are either Links or LinkTemplates + * (nested or not). * - * The query engine we implement here uses the Nodes/Links values that satisfy the leaves in this - * tree and flows them up through the internal nodes (logical operators) until they reach the root - * of the tree. In this path, some links are dropped because they don't satisfy the properties - * required by the operators or they don't satisfy a proper unification in the set of variables. + * The query engine we implement here uses the Nodes/Links values that satisfy + * the leaves in this tree and flows them up through the internal nodes (logical + * operators) until they reach the root of the tree. In this path, some links + * are dropped because they don't satisfy the properties required by the + * operators or they don't satisfy a proper unification in the set of variables. * * Links that reach the root of the tree are considered actual query answers. * - * Each QueryElement is an element in a distributed algorithm, with one or more threads processing - * its inputs and generating outputs according to the logic of each element. A communication - * framework is used to flow the links up through the tree using our DistributedAlgorithmNode - * which is essentially a framework to implement the basic functionalities required by a - * distributed algorithm. Since this framework allows communication either intra-process and - * extra-process (in the same machine or in different ones), we can have QueryElements of the - * same tree (i.e. of the same query) being processed in different machines or all of them in the - * same machine (either in the same process or in different processes). + * Each QueryElement is an element in a distributed algorithm, with one or more + * threads processing its inputs and generating outputs according to the logic + * of each element. A communication framework is used to flow the links up + * through the tree using our DistributedAlgorithmNode which is essentially a + * framework to implement the basic functionalities required by a distributed + * algorithm. Since this framework allows communication either intra-process and + * extra-process (in the same machine or in different ones), we can have + * QueryElements of the same tree (i.e. of the same query) being processed in + * different machines or all of them in the same machine (either in the same + * process or in different processes). */ class QueryElement { - -public: - + public: string id; string subsequent_id; @@ -69,50 +75,51 @@ class QueryElement { // API to be extended by concrete subclasses /** - * Setup QueryNodes used by concrete implementations of QueryElements. This method is called - * after all ids and other topological-related setup in the query tree is finished. + * Setup QueryNodes used by concrete implementations of QueryElements. This + * method is called after all ids and other topological-related setup in the + * query tree is finished. */ virtual void setup_buffers() = 0; /** - * Synchronously request this QueryElement to shutdown any threads it may have spawned. + * Synchronously request this QueryElement to shutdown any threads it may have + * spawned. */ virtual void graceful_shutdown() = 0; /** - * Indicates whether this QueryElement is a Terminal (i.e. Node, Link or Variable). + * Indicates whether this QueryElement is a Terminal (i.e. Node, Link or + * Variable). */ bool is_terminal; -protected: - + protected: /** - * Return true iff this QueryElement have finished its work in the flow of links up through - * the query tree. + * Return true iff this QueryElement have finished its work in the flow of + * links up through the query tree. * - * When this method return true, it means that all the QueryElements below than in the chain - * have already provided all the links they are supposed to and this QueryElement have already - * processed all of them and delivered all the links that are supposed to pass through the flow - * to the upper element in the tree. In other words, this QueryElement have no further work - * to do. + * When this method return true, it means that all the QueryElements below + * than in the chain have already provided all the links they are supposed to + * and this QueryElement have already processed all of them and delivered all + * the links that are supposed to pass through the flow to the upper element + * in the tree. In other words, this QueryElement have no further work to do. * - * @return true iff this QueryElement have finished its work in the flow of links up througth - * the query tree. + * @return true iff this QueryElement have finished its work in the flow of + * links up througth the query tree. */ bool is_flow_finished(); /** - * Sets a flag to indicate that this QueryElement have finished its work in the query. See - * comments in method is_flow_finished(). + * Sets a flag to indicate that this QueryElement have finished its work in + * the query. See comments in method is_flow_finished(). */ void set_flow_finished(); -private: - + private: bool flow_finished; mutex flow_finished_mutex; }; -} // namespace query_element +} // namespace query_element -#endif // _QUERY_ELEMENT_QUERYELEMENT_H +#endif // _QUERY_ELEMENT_QUERYELEMENT_H diff --git a/src/query_engine/query_element/RemoteIterator.h b/src/query_engine/query_element/RemoteIterator.h index af9802a..8c52c6a 100644 --- a/src/query_engine/query_element/RemoteIterator.h +++ b/src/query_engine/query_element/RemoteIterator.h @@ -1,38 +1,37 @@ #ifndef _QUERY_ELEMENT_REMOTEITERATOR_H #define _QUERY_ELEMENT_REMOTEITERATOR_H -#include "QueryElement.h" #include "QueryAnswer.h" +#include "QueryElement.h" using namespace std; namespace query_element { /** - * A special case of QueryElement because RemoteIterator is not actually an element of the - * query tree itself but rather a utility class used to remotely connect to the sink of a query - * tree (RemoteSink). + * A special case of QueryElement because RemoteIterator is not actually an + * element of the query tree itself but rather a utility class used to remotely + * connect to the sink of a query tree (RemoteSink). * - * Basically, the goal of this class is to allow a caller to request a query execution remotely - * and iterate through the results using the RemoteIterator. + * Basically, the goal of this class is to allow a caller to request a query + * execution remotely and iterate through the results using the RemoteIterator. * - * NB Like Iterator in this same package, this is not a std::iterator as the behavior we'd expect - * of a std::iterator doesn't fit well with the asynchronous nature of QueryElement processing. - * Instead, this class provides only two methods: one to pop and return the next - * query answers and another to check if more answers can still be expected. + * NB Like Iterator in this same package, this is not a std::iterator as the + * behavior we'd expect of a std::iterator doesn't fit well with the + * asynchronous nature of QueryElement processing. Instead, this class provides + * only two methods: one to pop and return the next query answers and another to + * check if more answers can still be expected. */ template class RemoteIterator : public QueryElement { - -public: - + public: /** * Constructor. * - * @param local_id The id of this element in the network which connects to the RemoteSink. - * Typically is something like "host:port". + * @param local_id The id of this element in the network which connects to the + * RemoteSink. Typically is something like "host:port". */ - RemoteIterator(const string &local_id); + RemoteIterator(const string& local_id); /** * Destructor. @@ -49,33 +48,34 @@ class RemoteIterator : public QueryElement { // Iterator API /** - * Return true when all query answers has been processed AND all the query answers - * that reached this QueryElement has been pop'ed out using the method pop(). + * Return true when all query answers has been processed AND all the query + * answers that reached this QueryElement has been pop'ed out using the method + * pop(). * - * @return true iff all query answers has been processed AND all the query answers - * that reached this QueryElement has been pop'ed out using the method pop(). + * @return true iff all query answers has been processed AND all the query + * answers that reached this QueryElement has been pop'ed out using the method + * pop(). */ bool finished(); /** * Return the next query answer or NULL if none are currently available. * - * NB a NULL return DOESN'T mean that the query answers are over. It means that there - * are no query answers available now. Because of the asynchronous nature of QueryElement - * processing, more query answers can arrive later. + * NB a NULL return DOESN'T mean that the query answers are over. It means + * that there are no query answers available now. Because of the asynchronous + * nature of QueryElement processing, more query answers can arrive later. * * @return the next query answer or NULL if none are currently available. */ - QueryAnswer *pop(); - -private: + QueryAnswer* pop(); + private: shared_ptr> remote_input_buffer; string local_id; }; -} // namespace query_element +} // namespace query_element #include "RemoteIterator.cc" -#endif // _QUERY_ELEMENT_REMOTEITERATOR_H +#endif // _QUERY_ELEMENT_REMOTEITERATOR_H diff --git a/src/query_engine/query_element/RemoteSink.h b/src/query_engine/query_element/RemoteSink.h index 04f74c9..04d0063 100644 --- a/src/query_engine/query_element/RemoteSink.h +++ b/src/query_engine/query_element/RemoteSink.h @@ -12,7 +12,8 @@ using namespace std; namespace query_element { /** - * A special sink which forwards the query results to a remote QueryElement (e.g. a RemoteIterator). + * A special sink which forwards the query results to a remote QueryElement + * (e.g. a RemoteIterator). */ template class RemoteSink : public Sink { @@ -21,9 +22,11 @@ class RemoteSink : public Sink { * Constructor. * * @param precedent QueryElement just below in the query tree. - * @param query_answer_processors List of processors to be applied to the query answers. - * @param delete_precedent_on_destructor If true, the destructor of this QueryElement will - * also destruct the passed precedent QueryElement (defaulted to false). + * @param query_answer_processors List of processors to be applied to the + * query answers. + * @param delete_precedent_on_destructor If true, the destructor of this + * QueryElement will also destruct the passed precedent QueryElement + * (defaulted to false). */ RemoteSink(QueryElement* precedent, vector>&& query_answer_processors, @@ -38,8 +41,8 @@ class RemoteSink : public Sink { // QueryElement API /** - * Gracefully shuts down the queue processor thread and the remote communication QueryNodes - * present in this QueryElement. + * Gracefully shuts down the queue processor thread and the remote + * communication QueryNodes present in this QueryElement. */ virtual void graceful_shutdown(); diff --git a/src/query_engine/query_element/Sink.cc b/src/query_engine/query_element/Sink.cc index 3735d3a..8246c82 100644 --- a/src/query_engine/query_element/Sink.cc +++ b/src/query_engine/query_element/Sink.cc @@ -8,12 +8,10 @@ using namespace query_element; // Constructors and destructors template -Sink::Sink( - QueryElement *precedent, - const string &id, - bool delete_precedent_on_destructor, - bool setup_buffers_flag) { - +Sink::Sink(QueryElement* precedent, + const string& id, + bool delete_precedent_on_destructor, + bool setup_buffers_flag) { this->precedent = precedent; this->id = id; this->delete_precedent_on_destructor = delete_precedent_on_destructor; diff --git a/src/query_engine/query_element/Sink.h b/src/query_engine/query_element/Sink.h index b0b84dd..3054cf0 100644 --- a/src/query_engine/query_element/Sink.h +++ b/src/query_engine/query_element/Sink.h @@ -8,35 +8,37 @@ using namespace std; namespace query_element { /** - * Superclass for elements that represent the root in a query tree of QueryElement. + * Superclass for elements that represent the root in a query tree of + * QueryElement. * - * It's a "sink" in the sense of being an element where the flow of links stops, going - * nowhere further. + * It's a "sink" in the sense of being an element where the flow of links stops, + * going nowhere further. * - * Sink adds the required DistributedAlgorithmNode (actually a specialized version of it - * named QueryNode) and exposes a public API to interact with it transparently. Basically, - * a server version of QueryNode (i.e. a ServerQueryNode) is setup to communicate with - * a remote ClientQueryNode which is located in the QueryElement just below in the query tree. + * Sink adds the required DistributedAlgorithmNode (actually a specialized + * version of it named QueryNode) and exposes a public API to interact with it + * transparently. Basically, a server version of QueryNode (i.e. a + * ServerQueryNode) is setup to communicate with a remote ClientQueryNode which + * is located in the QueryElement just below in the query tree. */ template class Sink : public QueryElement { - -public: - + public: /** - * Constructor expects that the QueryElement below in the tree is already constructed. + * Constructor expects that the QueryElement below in the tree is already + * constructed. * * @param precedent QueryElement just below in the query tree. * @param id Unique id for this QueryElement. - * @param delete_precedent_on_destructor If true, the destructor of this QueryElement will - * also destruct the passed precedent QueryElement (defaulted to false). - * @param setup_buffers_flag If true, the setup_buffers() method is called in the constructor. + * @param delete_precedent_on_destructor If true, the destructor of this + * QueryElement will also destruct the passed precedent QueryElement + * (defaulted to false). + * @param setup_buffers_flag If true, the setup_buffers() method is called in + * the constructor. */ - Sink( - QueryElement *precedent, - const string &id, - bool delete_precedent_on_destructor = false, - bool setup_buffers_flag = true); + Sink(QueryElement* precedent, + const string& id, + bool delete_precedent_on_destructor = false, + bool setup_buffers_flag = true); /** * Destructor. @@ -52,23 +54,21 @@ class Sink : public QueryElement { virtual void graceful_shutdown(); /** - * Setup a ServerQueryNode to commnunicate with one or more QueryElement just below in the - * query tree. + * Setup a ServerQueryNode to commnunicate with one or more QueryElement just + * below in the query tree. */ virtual void setup_buffers(); -protected: - + protected: shared_ptr> input_buffer; - QueryElement *precedent; - -private: + QueryElement* precedent; + private: bool delete_precedent_on_destructor; }; -} // namespace query_element +} // namespace query_element #include "Sink.cc" -#endif // _QUERY_ELEMENT_SINK_H +#endif // _QUERY_ELEMENT_SINK_H diff --git a/src/query_engine/query_element/Source.h b/src/query_engine/query_element/Source.h index 48b3821..fa51240 100644 --- a/src/query_engine/query_element/Source.h +++ b/src/query_engine/query_element/Source.h @@ -9,20 +9,22 @@ using namespace std; namespace query_element { /** - * Superclass for elements that represent leaves in the query tree of QueryElement. + * Superclass for elements that represent leaves in the query tree of + * QueryElement. * - * Source adds the required DistributedAlgorithmNode (actually a specialized version of it - * named QueryNode) and exposes a public API to interact with it transparently. Basically, - * a client version of QueryNode (i.e. a ClientQueryNode) is setup to communicate with - * a remote ServerQueryNode which is located in the QueryElement just above in the query tree. + * Source adds the required DistributedAlgorithmNode (actually a specialized + * version of it named QueryNode) and exposes a public API to interact with it + * transparently. Basically, a client version of QueryNode (i.e. a + * ClientQueryNode) is setup to communicate with a remote ServerQueryNode which + * is located in the QueryElement just above in the query tree. */ class Source : public QueryElement { public: /** - * Sources tipically need to communicate with the AttentionBroker in order to sort links - * by importance. AttentionBroker is supposed to be running in the same machine as all - * Source elements so only a port number is required. Here we provide a default value - * in the case none is passed in constructor. + * Sources tipically need to communicate with the AttentionBroker in order to + * sort links by importance. AttentionBroker is supposed to be running in the + * same machine as all Source elements so only a port number is required. Here + * we provide a default value in the case none is passed in constructor. */ static string DEFAULT_ATTENTION_BROKER_PORT; diff --git a/src/query_engine/query_element/Terminal.h b/src/query_engine/query_element/Terminal.h index 555ea22..f86e326 100644 --- a/src/query_engine/query_element/Terminal.h +++ b/src/query_engine/query_element/Terminal.h @@ -1,10 +1,11 @@ #ifndef _QUERY_ELEMENT_TERMINAL_H #define _QUERY_ELEMENT_TERMINAL_H -#include #include -#include "QueryElement.h" +#include + #include "AtomDB.h" +#include "QueryElement.h" #include "expression_hasher.h" using namespace std; @@ -16,27 +17,25 @@ namespace query_element { // Abstract Terminal superclass /** - * A QueryElement which represents terminals (i.e. Nodes, Links and Variables) in the query tree. + * A QueryElement which represents terminals (i.e. Nodes, Links and Variables) + * in the query tree. */ class Terminal : public QueryElement { - -protected: - + protected: /** * Protected constructor. */ Terminal() : QueryElement() { this->handle = shared_ptr{}; this->is_variable = false; - this->is_terminal = true; // overrrides QueryElement default + this->is_terminal = true; // overrrides QueryElement default } -public: - + public: /** * Destructor. */ - ~Terminal() {}; + ~Terminal(){}; /** * Empty implementation. There are no QueryNode element to setup. @@ -44,13 +43,14 @@ class Terminal : public QueryElement { void virtual setup_buffers() {} /** - * Empty implementation. There are no QueryNode element or local thread to shut down. + * Empty implementation. There are no QueryNode element or local thread to + * shut down. */ void virtual graceful_shutdown() {} - + /** - * Returns a string representation of this Terminal (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Terminal (mainly for debugging; not + * optimized to production environment). */ virtual string to_string() = 0; @@ -67,7 +67,8 @@ class Terminal : public QueryElement { /** * Name of the terminal. * - * Actually, only Nodes and Variables have names; Links' name is an empty string. + * Actually, only Nodes and Variables have names; Links' name is an empty + * string. */ string name; }; @@ -79,24 +80,22 @@ class Terminal : public QueryElement { * QueryElement which represents a node. */ class Node : public Terminal { - -public: - + public: /** * Constructor. * * @param type Type of the node. * @param name Name of the node. */ - Node(const string &type, const string &name) : Terminal() { + Node(const string& type, const string& name) : Terminal() { this->type = type; this->name = name; - this->handle = shared_ptr(terminal_hash((char *) type.c_str(), (char *) name.c_str())); + this->handle = shared_ptr(terminal_hash((char*) type.c_str(), (char*) name.c_str())); } /** - * Returns a string representation of this Node (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Node (mainly for debugging; not + * optimized to production environment). */ string to_string() { return "<" + this->type + ", " + this->name + ", " + string(this->handle.get()) + ">"; @@ -116,26 +115,25 @@ class Node : public Terminal { */ template class Link : public Terminal { - -public: - + public: /** * Constructor. * * @param type Type of the Link. * @params targets Array with targets of the Link. Targets are supposed to be - * handles (i.e. strings). No nesting of Nodes or other Links are allowed. + * handles (i.e. strings). No nesting of Nodes or other Links are + * allowed. */ - Link(const string &type, const array &targets) : Terminal() { + Link(const string& type, const array& targets) : Terminal() { this->name = ""; this->type = type; this->targets = targets; this->arity = ARITY; - char *handle_keys[ARITY + 1]; - handle_keys[0] = (char *) named_type_hash((char *) type.c_str()); + char* handle_keys[ARITY + 1]; + handle_keys[0] = (char*) named_type_hash((char*) type.c_str()); for (unsigned int i = 1; i < (ARITY + 1); i++) { - if (targets[i - 1]->is_terminal && ! ((Terminal *) targets[i - 1])->is_variable) { - handle_keys[i] = ((Terminal *) targets[i - 1])->handle.get(); + if (targets[i - 1]->is_terminal && !((Terminal*) targets[i - 1])->is_variable) { + handle_keys[i] = ((Terminal*) targets[i - 1])->handle.get(); } else { Utils::error("Invalid Link definition"); } @@ -145,13 +143,13 @@ class Link : public Terminal { } /** - * Returns a string representation of this Node (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Node (mainly for debugging; not + * optimized to production environment). */ string to_string() { string answer = "(" + this->type + ", ["; for (unsigned int i = 0; i < this->arity; i++) { - answer += ((Terminal *) this->targets[i])->to_string(); + answer += ((Terminal*) this->targets[i])->to_string(); if (i != (this->arity - 1)) { answer += ", "; } @@ -173,7 +171,7 @@ class Link : public Terminal { /** * Targets of the Link. */ - array targets; + array targets; }; // ------------------------------------------------------------------------------------------------- @@ -183,29 +181,25 @@ class Link : public Terminal { * QueryElement which represents a variable. */ class Variable : public Terminal { - -public: - + public: /** * Constructor. * * @param name Name of the Variable. */ - Variable(const string &name) : Terminal() { + Variable(const string& name) : Terminal() { this->name = name; - this->handle = shared_ptr(strdup((char *) AtomDB::WILDCARD.c_str())); + this->handle = shared_ptr(strdup((char*) AtomDB::WILDCARD.c_str())); this->is_variable = true; } /** - * Returns a string representation of this Variable (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Variable (mainly for debugging; not + * optimized to production environment). */ - string to_string() { - return "$(" + this->name + ")"; - } + string to_string() { return "$(" + this->name + ")"; } }; -} // namespace query_element +} // namespace query_element -#endif // _QUERY_ELEMENT_TERMINAL_H +#endif // _QUERY_ELEMENT_TERMINAL_H diff --git a/src/scripts/bazel.sh b/src/scripts/bazel.sh index 03e306a..ea6470a 100755 --- a/src/scripts/bazel.sh +++ b/src/scripts/bazel.sh @@ -9,29 +9,17 @@ BAZEL_CMD="/opt/bazel/bazelisk" # local paths LOCAL_WORKDIR=$(pwd) LOCAL_BIN_DIR=$LOCAL_WORKDIR/src/bin -LOCAL_ASPECT_CACHE="$HOME/.cache/das/aspect" -LOCAL_BAZEL_CACHE="$HOME/.cache/das/bazel" -LOCAL_BAZELISK_CACHE="$HOME/.cache/das/bazelisk" -LOCAL_PIPTOOLS_CACHE="$HOME/.cache/das/pip-tools" -LOCAL_PIP_CACHE="$HOME/.cache/das/pip" +LOCAL_CACHE="$HOME/.cache/das" mkdir -p \ - "$LOCAL_ASPECT_CACHE" \ "$LOCAL_BIN_DIR" \ - "$LOCAL_BAZEL_CACHE" \ - "$LOCAL_BAZELISK_CACHE" \ - "$LOCAL_PIPTOOLS_CACHE" \ - "$LOCAL_PIP_CACHE" + "$LOCAL_CACHE" # container paths CONTAINER_WORKDIR=/opt/das CONTAINER_WORKSPACE_DIR=/opt/das/src CONTAINER_BIN_DIR=$CONTAINER_WORKSPACE_DIR/bin -CONTAINER_ASPECT_CACHE=/home/"${USER}"/.cache/aspect -CONTAINER_BAZEL_CACHE=/home/"${USER}"/.cache/bazel -CONTAINER_PIP_CACHE=/home/"${USER}"/.cache/pip -CONTAINER_PIPTOOLS_CACHE=/home/"${USER}"/.cache/pip-tools -CONTAINER_BAZELISK_CACHE=/home/"${USER}"/.cache/bazelisk +CONTAINER_CACHE="/home/$USER/.cache" if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then echo "Removing existing container: ${CONTAINER_NAME}" @@ -44,11 +32,7 @@ docker run --rm \ -e BIN_DIR=$CONTAINER_BIN_DIR \ --network=host \ --volume /etc/passwd:/etc/passwd:ro \ - --volume "$LOCAL_PIP_CACHE":"$CONTAINER_PIP_CACHE" \ - --volume "$LOCAL_PIPTOOLS_CACHE":"$CONTAINER_PIPTOOLS_CACHE" \ - --volume "$LOCAL_ASPECT_CACHE":"$CONTAINER_ASPECT_CACHE" \ - --volume "$LOCAL_BAZEL_CACHE":"$CONTAINER_BAZEL_CACHE" \ - --volume "$LOCAL_BAZELISK_CACHE":"$CONTAINER_BAZELISK_CACHE" \ + --volume "$LOCAL_CACHE":"$CONTAINER_CACHE" \ --volume "$LOCAL_WORKDIR":"$CONTAINER_WORKDIR" \ --workdir "$CONTAINER_WORKSPACE_DIR" \ --entrypoint "$BAZEL_CMD" \ diff --git a/src/scripts/build.sh b/src/scripts/build.sh index 86c71e6..fe405b0 100755 --- a/src/scripts/build.sh +++ b/src/scripts/build.sh @@ -8,28 +8,16 @@ CONTAINER_NAME=${IMAGE_NAME}-container # local paths LOCAL_WORKDIR=$(pwd) LOCAL_BIN_DIR=$LOCAL_WORKDIR/src/bin -LOCAL_ASPECT_CACHE="$HOME/.cache/das/aspect" -LOCAL_BAZEL_CACHE="$HOME/.cache/das/bazel" -LOCAL_BAZELISK_CACHE="$HOME/.cache/das/bazelisk" -LOCAL_PIPTOOLS_CACHE="$HOME/.cache/das/pip-tools" -LOCAL_PIP_CACHE="$HOME/.cache/das/pip" +LOCAL_CACHE="${HOME}/.cache/das" mkdir -p \ - $LOCAL_ASPECT_CACHE \ - $LOCAL_BAZEL_CACHE \ - $LOCAL_BAZELISK_CACHE \ $LOCAL_BIN_DIR \ - $LOCAL_PIPTOOLS_CACHE \ - $LOCAL_PIP_CACHE + $LOCAL_CACHE # container paths CONTAINER_WORKDIR=/opt/das CONTAINER_WORKSPACE_DIR=/opt/das/src CONTAINER_BIN_DIR=$CONTAINER_WORKSPACE_DIR/bin -CONTAINER_ASPECT_CACHE=/home/${USER}/.cache/aspect -CONTAINER_BAZEL_CACHE=/home/${USER}/.cache/bazel -CONTAINER_PIP_CACHE=/home/${USER}/.cache/pip -CONTAINER_PIPTOOLS_CACHE=/home/${USER}/.cache/pip-tools -CONTAINER_BAZELISK_CACHE=/home/${USER}/.cache/bazelisk +CONTAINER_CACHE="/home/${USER}/.cache" if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then echo "Removing existing container: ${CONTAINER_NAME}" @@ -41,11 +29,7 @@ docker run --rm \ --name=$CONTAINER_NAME \ -e BIN_DIR=$CONTAINER_BIN_DIR \ --volume /etc/passwd:/etc/passwd:ro \ - --volume $LOCAL_PIP_CACHE:$CONTAINER_PIP_CACHE \ - --volume $LOCAL_PIPTOOLS_CACHE:$CONTAINER_PIPTOOLS_CACHE \ - --volume $LOCAL_ASPECT_CACHE:$CONTAINER_ASPECT_CACHE \ - --volume $LOCAL_BAZEL_CACHE:$CONTAINER_BAZEL_CACHE \ - --volume $LOCAL_BAZELISK_CACHE:$CONTAINER_BAZELISK_CACHE \ + --volume $LOCAL_CACHE:$CONTAINER_CACHE \ --volume $LOCAL_WORKDIR:$CONTAINER_WORKDIR \ --workdir $CONTAINER_WORKSPACE_DIR \ ${IMAGE_NAME} \ diff --git a/src/tests/cpp/and_operator_test.cc b/src/tests/cpp/and_operator_test.cc index e454485..89fa401 100644 --- a/src/tests/cpp/and_operator_test.cc +++ b/src/tests/cpp/and_operator_test.cc @@ -1,11 +1,11 @@ #include #include -#include "gtest/gtest.h" -#include "Source.h" -#include "Sink.h" -#include "HandlesAnswer.h" #include "And.h" +#include "HandlesAnswer.h" +#include "Sink.h" +#include "Source.h" +#include "gtest/gtest.h" #include "test_utils.h" using namespace query_engine; @@ -14,57 +14,44 @@ using namespace query_element; #define SLEEP_DURATION ((unsigned int) 1000) class TestSource : public Source { - - public: - - TestSource(unsigned int count) { - this->id = "TestSource_" + to_string(count); + public: + TestSource(unsigned int count) { this->id = "TestSource_" + to_string(count); } + + ~TestSource() {} + + void add(const char* handle, + double importance, + const array& labels, + const array& values, + bool sleep_flag = true) { + HandlesAnswer* query_answer = new HandlesAnswer(handle, importance); + for (unsigned int i = 0; i < labels.size(); i++) { + query_answer->assignment.assign(labels[i], values[i]); } - - ~TestSource() { - } - - void add( - const char *handle, - double importance, - const array &labels, - const array &values, - bool sleep_flag = true) { - - HandlesAnswer *query_answer = new HandlesAnswer(handle, importance); - for (unsigned int i = 0; i < labels.size(); i++) { - query_answer->assignment.assign(labels[i], values[i]); - } - this->output_buffer->add_query_answer(query_answer); - if (sleep_flag) { - Utils::sleep(SLEEP_DURATION); - } + this->output_buffer->add_query_answer(query_answer); + if (sleep_flag) { + Utils::sleep(SLEEP_DURATION); } + } - void query_answers_finished() { - return this->output_buffer->query_answers_finished(); - } + void query_answers_finished() { return this->output_buffer->query_answers_finished(); } }; class TestSink : public Sink { - public: - TestSink(QueryElement *precedent) : - Sink(precedent, "TestSink(" + precedent->id + ")") { - } - ~TestSink() { - } - bool empty() { return this->input_buffer->is_query_answers_empty(); } - bool finished() { return this->input_buffer->is_query_answers_finished(); } - QueryAnswer *pop() { return this->input_buffer->pop_query_answer(); } + public: + TestSink(QueryElement* precedent) + : Sink(precedent, "TestSink(" + precedent->id + ")") {} + ~TestSink() {} + bool empty() { return this->input_buffer->is_query_answers_empty(); } + bool finished() { return this->input_buffer->is_query_answers_finished(); } + QueryAnswer* pop() { return this->input_buffer->pop_query_answer(); } }; -void check_query_answer( - string tag, - HandlesAnswer *query_answer, - double importance, - unsigned int handles_size, - const array &handles) { - +void check_query_answer(string tag, + HandlesAnswer* query_answer, + double importance, + unsigned int handles_size, + const array& handles) { cout << "check_query_answer(" + tag + ")" << endl; EXPECT_TRUE(double_equals(query_answer->importance, importance)); EXPECT_EQ(query_answer->handles_size, 2); @@ -74,14 +61,14 @@ void check_query_answer( } TEST(AndOperator, basics) { - TestSource source1(1); TestSource source2(2); And<2> and_operator({&source1, &source2}); TestSink sink(&and_operator); - HandlesAnswer *query_answer; + HandlesAnswer* query_answer; - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); // -------------------------------------------------- // Expected processing order: @@ -101,23 +88,30 @@ TEST(AndOperator, basics) { source1.add("h1_0", 0.5, {"v1_0"}, {"1"}); source2.add("h2_0", 0.3, {"v1_1"}, {"2"}); source2.add("h2_1", 0.2, {"v2_1"}, {"1"}); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); source1.add("h1_1", 0.4, {"v1_1"}, {"1"}); - EXPECT_FALSE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_FALSE(sink.empty()); + EXPECT_FALSE(sink.finished()); EXPECT_FALSE((query_answer = dynamic_cast(sink.pop())) == NULL); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); check_query_answer("1", query_answer, 0.5, 2, {"h1_0", "h2_0"}); EXPECT_TRUE(strcmp(query_answer->assignment.get("v1_0"), "1") == 0); EXPECT_TRUE(strcmp(query_answer->assignment.get("v1_1"), "2") == 0); source1.add("h1_2", 0.3, {"v1_2"}, {"1"}); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); source2.add("h2_2", 0.1, {"v2_2"}, {"1"}); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); source1.query_answers_finished(); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); source2.query_answers_finished(); Utils::sleep(SLEEP_DURATION); - EXPECT_FALSE(sink.empty()); EXPECT_TRUE(sink.finished()); + EXPECT_FALSE(sink.empty()); + EXPECT_TRUE(sink.finished()); // {"h1_1", "h2_0"} is not popped because it's invalid @@ -144,29 +138,29 @@ TEST(AndOperator, basics) { check_query_answer("9", query_answer, 0.3, 2, {"h1_2", "h2_2"}); Utils::sleep(SLEEP_DURATION); - EXPECT_TRUE(sink.empty()); EXPECT_TRUE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_TRUE(sink.finished()); } TEST(AndOperator, operation_logic) { - class ImportanceFitnessPair { - public: + public: double importance; double fitness; ImportanceFitnessPair() {} - ImportanceFitnessPair(const ImportanceFitnessPair &other) { + ImportanceFitnessPair(const ImportanceFitnessPair& other) { this->importance = other.importance; this->fitness = other.fitness; } - ImportanceFitnessPair& operator=(const ImportanceFitnessPair &other) { + ImportanceFitnessPair& operator=(const ImportanceFitnessPair& other) { this->importance = other.importance; this->fitness = other.fitness; return *this; } - bool operator<(const ImportanceFitnessPair &other) const { + bool operator<(const ImportanceFitnessPair& other) const { return this->fitness < other.fitness; } - bool operator>(const ImportanceFitnessPair &other) const { + bool operator>(const ImportanceFitnessPair& other) const { return this->fitness > other.fitness; } }; @@ -178,34 +172,26 @@ TEST(AndOperator, operation_logic) { array, 3> importance; priority_queue fitness_heap; ImportanceFitnessPair pair; - HandlesAnswer *query_answer; - TestSource *source[3]; + HandlesAnswer* query_answer; + TestSource* source[3]; for (unsigned int clause = 0; clause < clause_count; clause++) { source[clause] = new TestSource(clause); } - And<3> *and_operator = new And<3>((QueryElement **) source); - TestSink *sink = new TestSink(and_operator); + And<3>* and_operator = new And<3>((QueryElement**) source); + TestSink* sink = new TestSink(and_operator); for (unsigned int clause = 0; clause < clause_count; clause++) { for (unsigned int link = 0; link < link_count; link++) { importance[clause][link] = random_importance(); } - std::sort( - std::begin(importance[clause]), - std::end(importance[clause]), - std::greater{}); + std::sort(std::begin(importance[clause]), std::end(importance[clause]), std::greater{}); } cout << "QUEUES POPULATION" << endl; for (unsigned int clause = 0; clause < clause_count; clause++) { for (unsigned int link = 0; link < link_count; link++) { - source[clause]->add( - random_handle().c_str(), - importance[clause][link], - {"v"}, - {"1"}, - false); + source[clause]->add(random_handle().c_str(), importance[clause][link], {"v"}, {"1"}, false); } source[clause]->query_answers_finished(); } @@ -215,8 +201,10 @@ TEST(AndOperator, operation_logic) { for (unsigned int i = 0; i < link_count; i++) { for (unsigned int j = 0; j < link_count; j++) { for (unsigned int k = 0; k < link_count; k++) { - pair.importance = importance[0][i] > importance[1][j] ? importance[0][i] : importance[1][j]; - pair.importance = importance[2][k] > pair.importance ? importance[2][k] : pair.importance; + pair.importance = + importance[0][i] > importance[1][j] ? importance[0][i] : importance[1][j]; + pair.importance = + importance[2][k] > pair.importance ? importance[2][k] : pair.importance; pair.fitness = importance[0][i] * importance[1][j] * importance[2][k]; fitness_heap.push(pair); } @@ -227,14 +215,15 @@ TEST(AndOperator, operation_logic) { cout << "TEST CHECKS" << endl; unsigned int count = 0; - while (! (sink->empty() && sink->finished())) { + while (!(sink->empty() && sink->finished())) { if (sink->empty()) { Utils::sleep(); continue; } EXPECT_FALSE((query_answer = dynamic_cast(sink->pop())) == NULL); pair = fitness_heap.top(); - cout << count << " CHECK: " << query_answer->importance << " " << pair.importance << " (" << pair.fitness << ")" << endl; + cout << count << " CHECK: " << query_answer->importance << " " << pair.importance << " (" + << pair.fitness << ")" << endl; EXPECT_TRUE(double_equals(query_answer->importance, pair.importance)); fitness_heap.pop(); count++; diff --git a/src/tests/cpp/attention_broker_server_test.cc b/src/tests/cpp/attention_broker_server_test.cc index 42856a7..57656ad 100644 --- a/src/tests/cpp/attention_broker_server_test.cc +++ b/src/tests/cpp/attention_broker_server_test.cc @@ -1,18 +1,16 @@ -#include -#include - #include #include #include -#include "gtest/gtest.h" - -#include "common.pb.h" -#include "attention_broker.grpc.pb.h" -#include "attention_broker.pb.h" +#include +#include #include "AttentionBrokerServer.h" #include "Utils.h" +#include "attention_broker.grpc.pb.h" +#include "attention_broker.pb.h" +#include "common.pb.h" +#include "gtest/gtest.h" #include "test_utils.h" using namespace attention_broker_server; @@ -24,14 +22,13 @@ bool importance_equals(ImportanceType importance, double v2) { } TEST(AttentionBrokerTest, basics) { - AttentionBrokerServer service; dasproto::Empty empty; dasproto::HandleCount handle_count; dasproto::HandleList handle_list; dasproto::Ack ack; dasproto::ImportanceList importance_list; - ServerContext *context = NULL; + ServerContext* context = NULL; service.ping(context, &empty, &ack); EXPECT_EQ(ack.msg(), "PING"); @@ -44,8 +41,7 @@ TEST(AttentionBrokerTest, basics) { } TEST(AttentionBrokerTest, get_importance) { - - string *handles = build_handle_space(4); + string* handles = build_handle_space(4); AttentionBrokerServer service; dasproto::HandleList handle_list0; @@ -55,7 +51,7 @@ TEST(AttentionBrokerTest, get_importance) { dasproto::Ack ack; dasproto::ImportanceList importance_list1; dasproto::ImportanceList importance_list2; - ServerContext *context = NULL; + ServerContext* context = NULL; (*handle_count.mutable_map())[handles[0]] = 1; (*handle_count.mutable_map())[handles[1]] = 1; diff --git a/src/tests/cpp/das_node_test.cc b/src/tests/cpp/das_node_test.cc index 4cf19a5..feaef6e 100644 --- a/src/tests/cpp/das_node_test.cc +++ b/src/tests/cpp/das_node_test.cc @@ -1,21 +1,19 @@ #include -#include "gtest/gtest.h" -#include "DASNode.h" -#include "AtomDBSingleton.h" #include "AtomDB.h" -#include "Utils.h" +#include "AtomDBSingleton.h" +#include "DASNode.h" #include "HandlesAnswer.h" - +#include "Utils.h" +#include "gtest/gtest.h" #include "test_utils.h" using namespace query_engine; -string handle_to_atom(const char *handle) { - +string handle_to_atom(const char* handle) { shared_ptr db = AtomDBSingleton::get_instance(); shared_ptr document = db->get_atom_document(handle); - shared_ptr targets = db->query_for_targets((char *) handle); + shared_ptr targets = db->query_for_targets((char*) handle); string answer; if (targets != NULL) { @@ -42,18 +40,16 @@ string handle_to_atom(const char *handle) { return answer; } -void check_query( - vector &query, - unsigned int expected_count, - DASNode *das, - DASNode *requestor, - const string &context) { - +void check_query(vector& query, + unsigned int expected_count, + DASNode* das, + DASNode* requestor, + const string& context) { cout << "XXXXXXXXXXXXXXXX DASNode.queries CHECK BEGIN" << endl; - QueryAnswer *query_answer; - RemoteIterator *response = requestor->pattern_matcher_query(query, context); + QueryAnswer* query_answer; + RemoteIterator* response = requestor->pattern_matcher_query(query, context); unsigned int count = 0; - while (! response->finished()) { + while (!response->finished()) { while ((query_answer = response->pop()) == NULL) { if (response->finished()) { break; @@ -63,7 +59,7 @@ void check_query( } if (query_answer != NULL) { cout << "XXXXX " << query_answer->to_string() << endl; - //cout << "XXXXX " << handle_to_atom(query_answer->handles[0]) << endl; + // cout << "XXXXX " << handle_to_atom(query_answer->handles[0]) << endl; count++; } } @@ -77,7 +73,6 @@ void check_query( } TEST(DASNode, queries) { - cout << "XXXXXXXXXXXXXXXX DASNode.queries BEGIN" << endl; setenv("DAS_REDIS_HOSTNAME", "localhost", 1); @@ -91,74 +86,65 @@ TEST(DASNode, queries) { string das_id = "localhost:31700"; string requestor_id = "localhost:31701"; - DASNode *das = new DASNode(das_id); + DASNode* das = new DASNode(das_id); Utils::sleep(1000); - DASNode *requestor = new DASNode(requestor_id, das_id); + DASNode* requestor = new DASNode(requestor_id, das_id); Utils::sleep(1000); - vector q1 = { - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "VARIABLE", "v2" - }; + vector q1 = {"LINK_TEMPLATE", + "Expression", + "3", + "NODE", + "Symbol", + "Similarity", + "VARIABLE", + "v1", + "VARIABLE", + "v2"}; int q1_expected_count = 14; - vector q2 = { - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "NODE", "Symbol", "\"human\"", - "VARIABLE", "v1" - }; + vector q2 = {"LINK_TEMPLATE", + "Expression", + "3", + "NODE", + "Symbol", + "Similarity", + "NODE", + "Symbol", + "\"human\"", + "VARIABLE", + "v1"}; int q2_expected_count = 3; - vector q3 = { - "AND", "2", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "NODE", "Symbol", "\"human\"", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Inheritance", - "VARIABLE", "v1", - "NODE", "Symbol", "\"plant\"" - }; + vector q3 = {"AND", "2", "LINK_TEMPLATE", "Expression", "3", + "NODE", "Symbol", "Similarity", "VARIABLE", "v1", + "NODE", "Symbol", "\"human\"", "LINK_TEMPLATE", "Expression", + "3", "NODE", "Symbol", "Inheritance", "VARIABLE", + "v1", "NODE", "Symbol", "\"plant\""}; int q3_expected_count = 1; - vector q4 = { - "AND", "2", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "VARIABLE", "v2", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v2", - "VARIABLE", "v3" - }; + vector q4 = {"AND", "2", "LINK_TEMPLATE", "Expression", "3", + "NODE", "Symbol", "Similarity", "VARIABLE", "v1", + "VARIABLE", "v2", "LINK_TEMPLATE", "Expression", "3", + "NODE", "Symbol", "Similarity", "VARIABLE", "v2", + "VARIABLE", "v3"}; int q4_expected_count = 26; // TODO: FIX THIS count should be == 1 - vector q5 = { - "OR", "2", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "NODE", "Symbol", "\"human\"", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "NODE", "Symbol", "\"snake\"" - }; + vector q5 = {"OR", "2", "LINK_TEMPLATE", "Expression", "3", + "NODE", "Symbol", "Similarity", "VARIABLE", "v1", + "NODE", "Symbol", "\"human\"", "LINK_TEMPLATE", "Expression", + "3", "NODE", "Symbol", "Similarity", "VARIABLE", + "v1", "NODE", "Symbol", "\"snake\""}; int q5_expected_count = 5; check_query(q1, q1_expected_count, das, requestor, "DASNode.queries"); check_query(q2, q2_expected_count, das, requestor, "DASNode.queries"); check_query(q3, q3_expected_count, das, requestor, "DASNode.queries"); - check_query(q4, q4_expected_count, das, requestor, "DASNode.queries"); + check_query(q4, q4_expected_count, das, requestor, "DASNode.queries"); check_query(q5, q5_expected_count, das, requestor, "DASNode.queries"); - //delete(requestor); // TODO: Uncomment this - //delete(das); // TODO: Uncomment this + // delete(requestor); // TODO: Uncomment this + // delete(das); // TODO: Uncomment this cout << "XXXXXXXXXXXXXXXX DASNode.queries END" << endl; } diff --git a/src/tests/cpp/distributed_algorithm_node_test.cc b/src/tests/cpp/distributed_algorithm_node_test.cc index b15f65c..377b5a7 100644 --- a/src/tests/cpp/distributed_algorithm_node_test.cc +++ b/src/tests/cpp/distributed_algorithm_node_test.cc @@ -1,9 +1,9 @@ -#include #include +#include -#include "gtest/gtest.h" -#include "Utils.h" #include "DistributedAlgorithmNode.h" +#include "Utils.h" +#include "gtest/gtest.h" using namespace distributed_algorithm_node; @@ -11,7 +11,7 @@ using namespace distributed_algorithm_node; // Utility classes - concrete subclasses of DistributedAlgorithmNode and Message class TestMessage : public Message { -public: + public: string command; vector args; TestMessage(string command, vector args) { @@ -22,35 +22,28 @@ class TestMessage : public Message { }; class TestNode : public DistributedAlgorithmNode { - -public: - + public: string server_id; bool is_server; string command; vector args; unsigned int node_joined_network_count; - TestNode( - const string &node_id, - const string &server_id, - LeadershipBrokerType leadership_algorithm, - MessageBrokerType messaging_backend, - bool is_server) : DistributedAlgorithmNode( - node_id, - leadership_algorithm, - messaging_backend) { - + TestNode(const string& node_id, + const string& server_id, + LeadershipBrokerType leadership_algorithm, + MessageBrokerType messaging_backend, + bool is_server) + : DistributedAlgorithmNode(node_id, leadership_algorithm, messaging_backend) { this->is_server = is_server; - if (! is_server) { + if (!is_server) { this->server_id = server_id; this->add_peer(server_id); } this->node_joined_network_count = 0; } - virtual ~TestNode() { - } + virtual ~TestNode() {} string cast_leadership_vote() { if (this->is_server) { @@ -60,14 +53,14 @@ class TestNode : public DistributedAlgorithmNode { } } - void node_joined_network(const string &node_id) { + void node_joined_network(const string& node_id) { this->node_joined_network_count += 1; if (is_server) { this->add_peer(node_id); } } - std::shared_ptr message_factory(string &command, vector &args) { + std::shared_ptr message_factory(string& command, vector& args) { std::shared_ptr message = DistributedAlgorithmNode::message_factory(command, args); if (message) { return message; @@ -92,30 +85,17 @@ TEST(DistributedAlgorithmNode, basics) { string server_id = "localhost:30700"; string client1_id = "localhost:30701"; string client2_id = "localhost:30702"; - TestNode *server; - TestNode *client1; - TestNode *client2; - - for (auto messaging_type: {MessageBrokerType::RAM , MessageBrokerType::GRPC}) { + TestNode* server; + TestNode* client1; + TestNode* client2; + for (auto messaging_type : {MessageBrokerType::RAM, MessageBrokerType::GRPC}) { server = new TestNode( - server_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - true); + server_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, true); client1 = new TestNode( - client1_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - false); + client1_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, false); client2 = new TestNode( - client2_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - false); + client2_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, false); EXPECT_FALSE(server->is_leader()); EXPECT_FALSE(client1->is_leader()); @@ -152,40 +132,25 @@ TEST(DistributedAlgorithmNode, basics) { delete client1; delete client2; } - } TEST(DistributedAlgorithmNode, communication) { - string server_id = "localhost:30700"; string client1_id = "localhost:30701"; string client2_id = "localhost:30702"; - TestNode *server; - TestNode *client1; - TestNode *client2; - - for (auto messaging_type: {MessageBrokerType::RAM , MessageBrokerType::GRPC}) { + TestNode* server; + TestNode* client1; + TestNode* client2; + for (auto messaging_type : {MessageBrokerType::RAM, MessageBrokerType::GRPC}) { server = new TestNode( - server_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - true); + server_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, true); server->join_network(); client1 = new TestNode( - client1_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - false); + client1_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, false); client1->join_network(); client2 = new TestNode( - client2_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - false); + client2_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, false); client2->join_network(); Utils::sleep(1000); @@ -198,7 +163,8 @@ TEST(DistributedAlgorithmNode, communication) { EXPECT_EQ(server->node_joined_network_count, 2); EXPECT_EQ(client1->node_joined_network_count, 1); - EXPECT_EQ(client2->node_joined_network_count, 0); // TODO Fix this. This count should be 2 + EXPECT_EQ(client2->node_joined_network_count, + 0); // TODO Fix this. This count should be 2 vector args1 = {"a", "b"}; server->broadcast("c1", args1); diff --git a/src/tests/cpp/handle_trie_test.cc b/src/tests/cpp/handle_trie_test.cc index 10d936f..804f716 100644 --- a/src/tests/cpp/handle_trie_test.cc +++ b/src/tests/cpp/handle_trie_test.cc @@ -2,12 +2,11 @@ #include #include -#include "gtest/gtest.h" - -#include "Utils.h" -#include "expression_hasher.h" #include "HandleTrie.h" #include "RequestSelector.h" +#include "Utils.h" +#include "expression_hasher.h" +#include "gtest/gtest.h" #include "test_utils.h" #define HANDLE_SPACE_SIZE ((unsigned int) 100) @@ -15,26 +14,18 @@ using namespace attention_broker_server; using namespace std; -class TestValue: public HandleTrie::TrieValue { - public: - unsigned int count; - TestValue(int count = 1) { - this->count = count; - } - void merge(TrieValue *other) { - - } +class TestValue : public HandleTrie::TrieValue { + public: + unsigned int count; + TestValue(int count = 1) { this->count = count; } + void merge(TrieValue* other) {} }; -class AccumulatorValue: public HandleTrie::TrieValue { - public: - unsigned int count; - AccumulatorValue() { - this->count = 1; - } - void merge(TrieValue *other) { - count += ((AccumulatorValue *) other)->count; - } +class AccumulatorValue : public HandleTrie::TrieValue { + public: + unsigned int count; + AccumulatorValue() { this->count = 1; } + void merge(TrieValue* other) { count += ((AccumulatorValue*) other)->count; } }; char R_TLB[16] = { @@ -56,196 +47,192 @@ char R_TLB[16] = { 'f', }; -bool visit1(HandleTrie::TrieNode *node, void *data) { - TestValue *value = (TestValue *) node->value; - value->count += *((unsigned int *) data); +bool visit1(HandleTrie::TrieNode* node, void* data) { + TestValue* value = (TestValue*) node->value; + value->count += *((unsigned int*) data); return false; } -bool visit2(HandleTrie::TrieNode *node, void *data) { - TestValue *value = (TestValue *) node->value; +bool visit2(HandleTrie::TrieNode* node, void* data) { + TestValue* value = (TestValue*) node->value; value->count += 1; return false; } -void visitor3(HandleTrie *trie, unsigned int n) { +void visitor3(HandleTrie* trie, unsigned int n) { for (unsigned int i = 0; i < n; i++) { trie->traverse(Utils::flip_coin(), &visit2, NULL); } } - TEST(HandleTrieTest, basics) { - HandleTrie trie(4); - TestValue *value; + TestValue* value; trie.insert("ABCD", new TestValue(3)); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value == NULL); trie.insert("ABCF", new TestValue(4)); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); trie.insert("ABFD", new TestValue(5)); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5); trie.insert("FBCD", new TestValue(6)); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6); trie.insert("AFCD", new TestValue(7)); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7); - value = (TestValue *) trie.lookup("ABFF"); + value = (TestValue*) trie.lookup("ABFF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("AFCF"); + value = (TestValue*) trie.lookup("AFCF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("AFFD"); + value = (TestValue*) trie.lookup("AFFD"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FBCF"); + value = (TestValue*) trie.lookup("FBCF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FBFD"); + value = (TestValue*) trie.lookup("FBFD"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FFCD"); + value = (TestValue*) trie.lookup("FFCD"); EXPECT_TRUE(value == NULL); unsigned int delta = 7; trie.traverse(false, &visit1, &delta); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3 + delta); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4 + delta); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5 + delta); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6 + delta); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7 + delta); } TEST(HandleTrieTest, traverse) { - HandleTrie trie(4); - TestValue *value; + TestValue* value; trie.insert("ABCD", new TestValue(3)); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value == NULL); trie.insert("ABCF", new TestValue(4)); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); trie.insert("ABFD", new TestValue(5)); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5); trie.insert("FBCD", new TestValue(6)); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6); trie.insert("AFCD", new TestValue(7)); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7); - value = (TestValue *) trie.lookup("ABFF"); + value = (TestValue*) trie.lookup("ABFF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("AFCF"); + value = (TestValue*) trie.lookup("AFCF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("AFFD"); + value = (TestValue*) trie.lookup("AFFD"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FBCF"); + value = (TestValue*) trie.lookup("FBCF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FBFD"); + value = (TestValue*) trie.lookup("FBFD"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FFCD"); + value = (TestValue*) trie.lookup("FFCD"); EXPECT_TRUE(value == NULL); - vector visitors; + vector visitors; unsigned int n_visits = 100000; unsigned int n_threads = 32; for (unsigned int i = 0; i < n_threads; i++) { visitors.push_back(new thread(&visitor3, &trie, n_visits)); } - for (thread *t: visitors) { + for (thread* t : visitors) { t->join(); } - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value->count == 3 + n_visits * n_threads); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value->count == 4 + n_visits * n_threads); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value->count == 5 + n_visits * n_threads); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value->count == 6 + n_visits * n_threads); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value->count == 7 + n_visits * n_threads); } TEST(HandleTrieTest, merge) { - HandleTrie trie(4); trie.insert("ABCD", new AccumulatorValue()); @@ -265,27 +252,27 @@ TEST(HandleTrieTest, merge) { trie.insert("FFFD", new AccumulatorValue()); trie.insert("FFFF", new AccumulatorValue()); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABCD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABCF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFCD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFCF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFFD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFFF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBCD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBCF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBFD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBFF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFFD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFFF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABCD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABCF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFCD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFCF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFFD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFFF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBCD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBCF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBFD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBFF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFFD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFFF"))->count == 1); trie.insert("ABFF", new AccumulatorValue()); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFF"))->count == 2); trie.insert("FFCD", new AccumulatorValue()); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCD"))->count == 2); trie.insert("ABCD", new AccumulatorValue()); trie.insert("ABCF", new AccumulatorValue()); @@ -304,33 +291,32 @@ TEST(HandleTrieTest, merge) { trie.insert("FFFD", new AccumulatorValue()); trie.insert("FFFF", new AccumulatorValue()); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABCD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABCF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFF"))->count == 3); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFCD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFCF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFFD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFFF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBCD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBCF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBFD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBFF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCD"))->count == 3); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFFD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFFF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABCD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABCF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFF"))->count == 3); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFCD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFCF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFFD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFFF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBCD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBCF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBFD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBFF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCD"))->count == 3); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFFD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFFF"))->count == 2); } TEST(HandleTrieTest, random_stress) { - char buffer[1000]; map baseline; - TestValue *value; + TestValue* value; - for (unsigned int key_size: {2, 5, 10, 100}) { + for (unsigned int key_size : {2, 5, 10, 100}) { baseline.clear(); - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); for (unsigned int i = 0; i < 100000; i++) { for (unsigned int j = 0; j < key_size; j++) { buffer[j] = R_TLB[(rand() % 16)]; @@ -341,7 +327,7 @@ TEST(HandleTrieTest, random_stress) { baseline[s] = 0; } baseline[s] = baseline[s] + 1; - value = (TestValue *) trie->lookup(s); + value = (TestValue*) trie->lookup(s); if (value == NULL) { value = new TestValue(); trie->insert(s, value); @@ -350,7 +336,7 @@ TEST(HandleTrieTest, random_stress) { } } for (auto const& pair : baseline) { - value = (TestValue *) trie->lookup(pair.first); + value = (TestValue*) trie->lookup(pair.first); EXPECT_TRUE(value != NULL); EXPECT_EQ(pair.second, value->count); } @@ -361,12 +347,12 @@ TEST(HandleTrieTest, random_stress) { TEST(HandleTrieTest, hasher) { char buffer[1000]; map baseline; - TestValue *value; + TestValue* value; - for (unsigned int key_count: {1, 2, 5}) { + for (unsigned int key_count : {1, 2, 5}) { baseline.clear(); unsigned int key_size = (HANDLE_HASH_SIZE - 1) * key_count; - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); for (unsigned int i = 0; i < 100000; i++) { for (unsigned int j = 0; j < key_size; j++) { buffer[j] = R_TLB[(rand() % 16)]; @@ -377,7 +363,7 @@ TEST(HandleTrieTest, hasher) { baseline[s] = 0; } baseline[s] = baseline[s] + 1; - value = (TestValue *) trie->lookup(s); + value = (TestValue*) trie->lookup(s); if (value == NULL) { value = new TestValue(); trie->insert(s, value); @@ -386,7 +372,7 @@ TEST(HandleTrieTest, hasher) { } } for (auto const& pair : baseline) { - value = (TestValue *) trie->lookup(pair.first); + value = (TestValue*) trie->lookup(pair.first); EXPECT_EQ(pair.second, value->count); } delete trie; @@ -396,13 +382,13 @@ TEST(HandleTrieTest, hasher) { TEST(HandleTrieTest, benchmark) { char buffer[1000]; map baseline; - TestValue *value; + TestValue* value; StopWatch timer_std; StopWatch timer_trie; unsigned int n_insertions = 1000000; timer_std.start(); - for (unsigned int key_count: {1, 2, 5}) { + for (unsigned int key_count : {1, 2, 5}) { unsigned int key_size = (HANDLE_HASH_SIZE - 1) * key_count; for (unsigned int i = 0; i < n_insertions; i++) { for (unsigned int j = 0; j < key_size; j++) { @@ -419,16 +405,16 @@ TEST(HandleTrieTest, benchmark) { timer_std.stop(); timer_trie.start(); - for (unsigned int key_count: {1, 2, 5}) { + for (unsigned int key_count : {1, 2, 5}) { unsigned int key_size = (HANDLE_HASH_SIZE - 1) * key_count; - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); for (unsigned int i = 0; i < n_insertions; i++) { for (unsigned int j = 0; j < key_size; j++) { buffer[j] = R_TLB[(rand() % 16)]; } buffer[key_size] = 0; string s = buffer; - value = (TestValue *) trie->lookup(s); + value = (TestValue*) trie->lookup(s); if (value == NULL) { value = new TestValue(); trie->insert(s, value); @@ -442,12 +428,12 @@ TEST(HandleTrieTest, benchmark) { cout << "stdlib: " + timer_std.str_time() << endl; cout << "trie: " + timer_trie.str_time() << endl; cout << "=======================================================" << endl; - //EXPECT_EQ(true, false); + // EXPECT_EQ(true, false); } -void producer(HandleTrie *trie, unsigned int n_insertions) { +void producer(HandleTrie* trie, unsigned int n_insertions) { char buffer[1000]; - AccumulatorValue *value; + AccumulatorValue* value; unsigned int key_size = HANDLE_HASH_SIZE - 1; for (unsigned int i = 0; i < n_insertions; i++) { for (unsigned int j = 0; j < key_size; j++) { @@ -460,7 +446,7 @@ void producer(HandleTrie *trie, unsigned int n_insertions) { } } -void visitor(HandleTrie *trie, unsigned int n_visits) { +void visitor(HandleTrie* trie, unsigned int n_visits) { char buffer[1000]; unsigned int key_size = HANDLE_HASH_SIZE - 1; for (unsigned int i = 0; i < n_visits; i++) { @@ -473,8 +459,8 @@ void visitor(HandleTrie *trie, unsigned int n_visits) { } } -void producer2(HandleTrie *trie, unsigned int n_insertions, string *handles) { - AccumulatorValue *value; +void producer2(HandleTrie* trie, unsigned int n_insertions, string* handles) { + AccumulatorValue* value; for (unsigned int i = 0; i < n_insertions; i++) { string s = handles[rand() % HANDLE_SPACE_SIZE]; value = new AccumulatorValue(); @@ -482,7 +468,7 @@ void producer2(HandleTrie *trie, unsigned int n_insertions, string *handles) { } } -void visitor2(HandleTrie *trie, unsigned int n_visits, string *handles) { +void visitor2(HandleTrie* trie, unsigned int n_visits, string* handles) { for (unsigned int i = 0; i < n_visits; i++) { string s = handles[rand() % HANDLE_SPACE_SIZE]; trie->lookup(s); @@ -490,16 +476,16 @@ void visitor2(HandleTrie *trie, unsigned int n_visits, string *handles) { } TEST(HandleTrieTest, multithread) { - vector producers; - vector visitors; + vector producers; + vector visitors; unsigned int n_insertions = 10000; unsigned int n_visits = 10000; StopWatch timer; timer.start(); - for (int n_producers: {2, 10, 100}) { - for (int n_visitors: {2, 10, 100}) { + for (int n_producers : {2, 10, 100}) { + for (int n_visitors : {2, 10, 100}) { unsigned int key_size = HANDLE_HASH_SIZE - 1; - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); producers.clear(); visitors.clear(); for (int i = 0; i < n_producers; i++) { @@ -508,10 +494,10 @@ TEST(HandleTrieTest, multithread) { for (int i = 0; i < n_visitors; i++) { visitors.push_back(new thread(&visitor, trie, n_visits)); } - for (thread *t: producers) { + for (thread* t : producers) { t->join(); } - for (thread *t: visitors) { + for (thread* t : visitors) { t->join(); } delete trie; @@ -525,24 +511,24 @@ TEST(HandleTrieTest, multithread_limited_handle_set) { for (unsigned int i = 0; i < HANDLE_SPACE_SIZE; i++) { handles[i] = random_handle(); } - vector producers; - vector visitors; + vector producers; + vector visitors; unsigned int n_insertions = 100000; unsigned int n_visits = 100000; - for (int n_producers: {2, 10, 100}) { - for (int n_visitors: {2, 10, 100}) { + for (int n_producers : {2, 10, 100}) { + for (int n_visitors : {2, 10, 100}) { unsigned int key_size = HANDLE_HASH_SIZE - 1; - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); for (int i = 0; i < n_producers; i++) { producers.push_back(new thread(&producer2, trie, n_insertions, handles)); } for (int i = 0; i < n_visitors; i++) { visitors.push_back(new thread(&visitor2, trie, n_visits, handles)); } - for (thread *t: producers) { + for (thread* t : producers) { t->join(); } - for (thread *t: visitors) { + for (thread* t : visitors) { t->join(); } delete trie; diff --git a/src/tests/cpp/handles_answer_test.cc b/src/tests/cpp/handles_answer_test.cc index 6ef09f4..5203855 100644 --- a/src/tests/cpp/handles_answer_test.cc +++ b/src/tests/cpp/handles_answer_test.cc @@ -1,16 +1,15 @@ #include #include -#include "gtest/gtest.h" #include "HandlesAnswer.h" #include "Utils.h" +#include "gtest/gtest.h" #include "test_utils.h" using namespace query_engine; using namespace commons; TEST(HandlesAnswer, assignments_basics) { - Assignment mapping0; // Tests assign() @@ -78,7 +77,6 @@ TEST(HandlesAnswer, assignments_basics) { } TEST(HandlesAnswer, handles_answer_basics) { - // Tests add_handle() HandlesAnswer query_answer1("h1", 0); query_answer1.assignment.assign("v1", "1"); @@ -103,7 +101,7 @@ TEST(HandlesAnswer, handles_answer_basics) { EXPECT_TRUE(query_answer2.assignment.assign("v3", "x")); // Tests copy() - HandlesAnswer *query_answer3 = HandlesAnswer::copy(&query_answer2); + HandlesAnswer* query_answer3 = HandlesAnswer::copy(&query_answer2); EXPECT_EQ(query_answer3->handles_size, 3); EXPECT_TRUE(strcmp(query_answer3->handles[0], "h2") == 0); EXPECT_TRUE(strcmp(query_answer3->handles[1], "hx") == 0); @@ -114,13 +112,12 @@ TEST(HandlesAnswer, handles_answer_basics) { EXPECT_TRUE(query_answer3->assignment.assign("v4", "x")); } -void query_answers_equal(HandlesAnswer *qa1, HandlesAnswer *qa2) { +void query_answers_equal(HandlesAnswer* qa1, HandlesAnswer* qa2) { EXPECT_TRUE(double_equals(qa1->importance, qa2->importance)); EXPECT_EQ(qa1->to_string(), qa2->to_string()); } TEST(HandlesAnswer, tokenization) { - unsigned int NUM_TESTS = 100000; unsigned int MAX_HANDLES = 5; unsigned int MAX_ASSIGNMENTS = 10; @@ -134,9 +131,8 @@ TEST(HandlesAnswer, tokenization) { } unsigned int label_count = 0; for (unsigned int i = 0; i < num_assignments; i++) { - input.assignment.assign( - strdup(sequential_label(label_count).c_str()), - strdup(random_handle().c_str())); + input.assignment.assign(strdup(sequential_label(label_count).c_str()), + strdup(random_handle().c_str())); } query_answers_equal(&input, HandlesAnswer::copy(&input)); diff --git a/src/tests/cpp/hebbian_network_test.cc b/src/tests/cpp/hebbian_network_test.cc index 5f5518c..de2ee16 100644 --- a/src/tests/cpp/hebbian_network_test.cc +++ b/src/tests/cpp/hebbian_network_test.cc @@ -1,20 +1,19 @@ #include #include -#include -#include #include +#include +#include -#include "gtest/gtest.h" -#include "Utils.h" -#include "test_utils.h" #include "HebbianNetwork.h" +#include "Utils.h" #include "expression_hasher.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace attention_broker_server; using namespace commons; TEST(HebbianNetwork, basics) { - HebbianNetwork network; string h1 = prefixed_random_handle("a"); @@ -23,10 +22,10 @@ TEST(HebbianNetwork, basics) { string h4 = prefixed_random_handle("d"); string h5 = prefixed_random_handle("e"); - HebbianNetwork::Node *n1 = network.add_node(h1); - HebbianNetwork::Node *n2 = network.add_node(h2); - HebbianNetwork::Node *n3 = network.add_node(h3); - HebbianNetwork::Node *n4 = network.add_node(h4); + HebbianNetwork::Node* n1 = network.add_node(h1); + HebbianNetwork::Node* n2 = network.add_node(h2); + HebbianNetwork::Node* n3 = network.add_node(h3); + HebbianNetwork::Node* n4 = network.add_node(h4); EXPECT_TRUE(network.get_node_count(h1) == 1); EXPECT_TRUE(network.get_node_count(h2) == 1); @@ -52,7 +51,6 @@ TEST(HebbianNetwork, basics) { } TEST(HebbianNetwork, stress) { - HebbianNetwork network; StopWatch timer_insertion; StopWatch timer_lookup; @@ -61,7 +59,7 @@ TEST(HebbianNetwork, stress) { unsigned int num_insertions = (handle_space_size * 2) * (handle_space_size * 2); unsigned int num_lookups = 10 * num_insertions; - string *handles = build_handle_space(handle_space_size); + string* handles = build_handle_space(handle_space_size); timer_insertion.start(); timer_total.start(); @@ -69,8 +67,8 @@ TEST(HebbianNetwork, stress) { for (unsigned int i = 0; i < num_insertions; i++) { string h1 = handles[rand() % handle_space_size]; string h2 = handles[rand() % handle_space_size]; - HebbianNetwork::Node *n1 = network.add_node(h1); - HebbianNetwork::Node *n2 = network.add_node(h2); + HebbianNetwork::Node* n1 = network.add_node(h1); + HebbianNetwork::Node* n2 = network.add_node(h2); network.add_symmetric_edge(h1, h2, n1, n2); } @@ -93,7 +91,7 @@ TEST(HebbianNetwork, stress) { cout << "Lookups: " << timer_lookup.str_time() << endl; cout << "Total: " << timer_total.str_time() << endl; cout << "==================================================================" << endl; - //EXPECT_TRUE(false); + // EXPECT_TRUE(false); } TEST(HebbianNetwork, alienate_tokens) { @@ -103,22 +101,20 @@ TEST(HebbianNetwork, alienate_tokens) { EXPECT_TRUE(network.alienate_tokens() == 0.0); } -bool visit1(HandleTrie::TrieNode *node, void *data) { - ((HebbianNetwork::Node *) node->value)->importance = 1.0; +bool visit1(HandleTrie::TrieNode* node, void* data) { + ((HebbianNetwork::Node*) node->value)->importance = 1.0; return false; } -bool visit2( - HandleTrie::TrieNode *node, - HebbianNetwork::Node *source, - forward_list &targets, - unsigned int targets_size, - ImportanceType sum_weights, - void *data) { - - unsigned int fan_max = *((unsigned int *) data); +bool visit2(HandleTrie::TrieNode* node, + HebbianNetwork::Node* source, + forward_list& targets, + unsigned int targets_size, + ImportanceType sum_weights, + void* data) { + unsigned int fan_max = *((unsigned int*) data); double stimulus = 1.0 / (double) fan_max; - for (auto target: targets) { + for (auto target : targets) { target->importance += stimulus; source->importance -= stimulus; } diff --git a/src/tests/cpp/hebbian_network_updater_test.cc b/src/tests/cpp/hebbian_network_updater_test.cc index 5fd4db7..1201753 100644 --- a/src/tests/cpp/hebbian_network_updater_test.cc +++ b/src/tests/cpp/hebbian_network_updater_test.cc @@ -1,23 +1,23 @@ -#include #include +#include -#include "gtest/gtest.h" -#include "common.pb.h" +#include "HebbianNetwork.h" +#include "HebbianNetworkUpdater.h" #include "attention_broker.grpc.pb.h" #include "attention_broker.pb.h" -#include "test_utils.h" +#include "common.pb.h" #include "expression_hasher.h" -#include "HebbianNetwork.h" -#include "HebbianNetworkUpdater.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace attention_broker_server; TEST(HebbianNetworkUpdater, correlation) { - string *handles = build_handle_space(6); - HebbianNetwork *network = new HebbianNetwork(); - dasproto::HandleList *request; - ExactCountHebbianUpdater *updater = \ - (ExactCountHebbianUpdater *) HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); + string* handles = build_handle_space(6); + HebbianNetwork* network = new HebbianNetwork(); + dasproto::HandleList* request; + ExactCountHebbianUpdater* updater = (ExactCountHebbianUpdater*) HebbianNetworkUpdater::factory( + HebbianNetworkUpdaterType::EXACT_COUNT); request = new dasproto::HandleList(); request->set_hebbian_network((unsigned long) network); diff --git a/src/tests/cpp/iterator_test.cc b/src/tests/cpp/iterator_test.cc index c7ed714..a1806ea 100644 --- a/src/tests/cpp/iterator_test.cc +++ b/src/tests/cpp/iterator_test.cc @@ -1,22 +1,21 @@ +#include "Iterator.h" + #include -#include "gtest/gtest.h" -#include "QueryNode.h" -#include "LinkTemplate.h" #include "AtomDBSingleton.h" -#include "test_utils.h" -#include "Iterator.h" #include "HandlesAnswer.h" +#include "LinkTemplate.h" +#include "QueryNode.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace query_engine; using namespace query_element; using namespace query_node; class TestQueryElement : public QueryElement { - public: - TestQueryElement(const string &id) { - this->id = id; - } + public: + TestQueryElement(const string& id) { this->id = id; } void setup_buffers() {} void graceful_shutdown() {} }; @@ -31,7 +30,7 @@ TEST(Iterator, basics) { EXPECT_FALSE(query_answer_iterator.finished()); - HandlesAnswer *qa; + HandlesAnswer* qa; HandlesAnswer qa0("h0", 0.0); HandlesAnswer qa1("h1", 0.1); HandlesAnswer qa2("h2", 0.2); @@ -70,7 +69,6 @@ TEST(Iterator, basics) { } TEST(Iterator, link_template_integration) { - setenv("DAS_REDIS_HOSTNAME", "localhost", 1); setenv("DAS_REDIS_PORT", "29000", 1); setenv("DAS_USE_REDIS_CLUSTER", "false", 1); @@ -92,18 +90,18 @@ TEST(Iterator, link_template_integration) { LinkTemplate<3> link_template("Expression", {&similarity, &human, &v1}); Iterator query_answer_iterator(&link_template); - string monkey_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"monkey\"")); - string chimp_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"chimp\"")); - string ent_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"ent\"")); + string monkey_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"monkey\"")); + string chimp_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"chimp\"")); + string ent_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"ent\"")); bool monkey_flag = false; bool chimp_flag = false; bool ent_flag = false; - HandlesAnswer *query_answer; - while (! query_answer_iterator.finished()) { + HandlesAnswer* query_answer; + while (!query_answer_iterator.finished()) { query_answer = dynamic_cast(query_answer_iterator.pop()); if (query_answer != NULL) { string var = string(query_answer->assignment.get("v1")); - //EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); + // EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); if (var == monkey_handle) { // TODO: perform extra checks monkey_flag = true; diff --git a/src/tests/cpp/leadership_broker_test.cc b/src/tests/cpp/leadership_broker_test.cc index 811fa15..0244a59 100644 --- a/src/tests/cpp/leadership_broker_test.cc +++ b/src/tests/cpp/leadership_broker_test.cc @@ -1,18 +1,17 @@ -#include #include +#include -#include "gtest/gtest.h" #include "LeadershipBroker.h" +#include "gtest/gtest.h" using namespace distributed_algorithm_node; TEST(LeadershipBroker, basics) { - try { LeadershipBroker::factory((LeadershipBrokerType) -1); FAIL() << "Expected exception"; - } catch(std::runtime_error const &error) { - } catch(...) { + } catch (std::runtime_error const& error) { + } catch (...) { FAIL() << "Expected std::runtime_error"; } diff --git a/src/tests/cpp/link_creation_agent_test.cc b/src/tests/cpp/link_creation_agent_test.cc index a243905..18d178c 100644 --- a/src/tests/cpp/link_creation_agent_test.cc +++ b/src/tests/cpp/link_creation_agent_test.cc @@ -1,10 +1,11 @@ +#include "link_creation_agent.h" + #include #include #include #include -#include "link_creation_agent.h" #include "link_create_template.h" using namespace std; @@ -113,13 +114,17 @@ vector split(const string& s, char delimiter) { } TEST(LinkCreateTemplate, TestLinkCreateTemplate) { - /** #NOTE Different from the original string test, the to_string() method is not returning the same - order as the input string. to_string is placing the custom fields after the targets + /** #NOTE Different from the original string test, the to_string() method is + not returning the same order as the input string. to_string is placing the + custom fields after the targets */ string link_template_str = - "LINK_CREATE Similarity 3 1 VARIABLE V1 LINK_CREATE Test 3 0 NODE Symbol A VARIABLE V2 " - "LINK_CREATE Test2 1 1 NODE Symbol C CUSTOM_FIELD inter 1 inter_name inter_value NODE Symbol B " - "CUSTOM_FIELD truth_value 2 CUSTOM_FIELD mean 2 count 10 avg 0.9 confidence 0.9"; + "LINK_CREATE Similarity 3 1 VARIABLE V1 " + "LINK_CREATE Test 3 0 NODE Symbol A VARIABLE V2 " + "LINK_CREATE Test2 1 1 NODE Symbol C CUSTOM_FIELD " + "inter 1 inter_name inter_value NODE Symbol B " + "CUSTOM_FIELD truth_value 2 CUSTOM_FIELD mean 2 " + "count 10 avg 0.9 confidence 0.9"; auto link_template = split(link_template_str, ' '); LinkCreateTemplate lct(link_template); EXPECT_EQ(lct.get_link_type(), "Similarity"); @@ -128,7 +133,8 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE I 3 0 VARIABLE V1 LINK_CREATE Test 3 0 NODE Symbol A VARIABLE V2 LINK_CREATE Test2 " + "LINK_CREATE I 3 0 VARIABLE V1 LINK_CREATE Test 3 0 NODE " + "Symbol A VARIABLE V2 LINK_CREATE Test2 " "1 0 NODE Symbol C NODE Symbol B"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct2(link_template); @@ -140,7 +146,8 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE Similarity 2 1 VARIABLE V1 VARIABLE V2 CUSTOM_FIELD truth_value 2 CUSTOM_FIELD " + "LINK_CREATE Similarity 2 1 VARIABLE V1 VARIABLE V2 " + "CUSTOM_FIELD truth_value 2 CUSTOM_FIELD " "mean 2 count 10 avg 0.9 confidence 0.9"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct3(link_template); @@ -150,7 +157,8 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE link_type 2 1 NODE type1 value1 VARIABLE var1 CUSTOM_FIELD field1 1 value1 value2"; + "LINK_CREATE link_type 2 1 NODE type1 value1 VARIABLE " + "var1 CUSTOM_FIELD field1 1 value1 value2"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct4(link_template); EXPECT_EQ(lct4.get_link_type(), "link_type"); @@ -159,14 +167,17 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE TestLink 4 1 NODE NodeType1 Value1 VARIABLE Var1 CUSTOM_FIELD Field1 2 valuename1 " + "LINK_CREATE TestLink 4 1 NODE NodeType1 Value1 VARIABLE Var1 " + "CUSTOM_FIELD Field1 2 valuename1 " "Value1 valuename2 Value2 NODE NodeType2 Value2 VARIABLE Var2"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct5(link_template); EXPECT_EQ(lct5.get_link_type(), "TestLink"); EXPECT_EQ(lct5.to_string(), - "LINK_CREATE TestLink 4 1 NODE NodeType1 Value1 VARIABLE Var1 NODE NodeType2 Value2 " - "VARIABLE Var2 CUSTOM_FIELD Field1 2 valuename1 Value1 valuename2 Value2"); + "LINK_CREATE TestLink 4 1 NODE NodeType1 Value1 " + "VARIABLE Var1 NODE NodeType2 Value2 " + "VARIABLE Var2 CUSTOM_FIELD Field1 2 valuename1 " + "Value1 valuename2 Value2"); EXPECT_EQ(lct5.get_targets().size(), 4); EXPECT_EQ(get(lct5.get_targets()[0]).type, "NodeType1"); EXPECT_EQ(get(lct5.get_targets()[0]).value, "Value1"); @@ -175,7 +186,8 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE AnotherLink 2 1 VARIABLE VarA NODE NodeTypeA ValueA CUSTOM_FIELD FieldA 1 NameA " + "LINK_CREATE AnotherLink 2 1 VARIABLE VarA NODE " + "NodeTypeA ValueA CUSTOM_FIELD FieldA 1 NameA " "ValueA"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct6(link_template); @@ -195,13 +207,15 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE ComplexLink 4 2 NODE Type1 Val1 VARIABLE Var1 CUSTOM_FIELD Field1 2 N1 Val1 N2 " + "LINK_CREATE ComplexLink 4 2 NODE Type1 Val1 VARIABLE Var1 CUSTOM_FIELD " + "Field1 2 N1 Val1 N2 " "Val2 NODE Type2 Val2 VARIABLE Var2 CUSTOM_FIELD Field2 1 N3 Val3"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct7(link_template); EXPECT_EQ(lct7.get_link_type(), "ComplexLink"); EXPECT_EQ(lct7.to_string(), - "LINK_CREATE ComplexLink 4 2 NODE Type1 Val1 VARIABLE Var1 NODE Type2 Val2 VARIABLE Var2 " + "LINK_CREATE ComplexLink 4 2 NODE Type1 Val1 VARIABLE Var1 NODE Type2 " + "Val2 VARIABLE Var2 " "CUSTOM_FIELD Field1 2 N1 Val1 N2 Val2 CUSTOM_FIELD Field2 1 N3 Val3"); EXPECT_EQ(lct7.get_targets().size(), 4); EXPECT_EQ(get(lct7.get_targets()[0]).type, "Type1"); @@ -223,7 +237,9 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template.clear(); link_template_str.clear(); - link_template_str = "LINK_CREATE SimpleLink 2 0 VARIABLE SimpleVar NODE SimpleNode SimpleValue"; + link_template_str = + "LINK_CREATE SimpleLink 2 0 VARIABLE SimpleVar NODE " + "SimpleNode SimpleValue"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct8(link_template); EXPECT_EQ(lct8.get_link_type(), "SimpleLink"); @@ -250,7 +266,8 @@ TEST(LinkCreateTemplate, TestInvalidTargetCount) { TEST(LinkCreateTemplate, TestInvalidCustomField) { string link_template_str = - "LINK_CREATE Similarity 2 1 VARIABLE V1 NODE Symbol A CUSTOM_FIELD field1"; + "LINK_CREATE Similarity 2 1 VARIABLE V1 NODE " + "Symbol A CUSTOM_FIELD field1"; auto link_template = split(link_template_str, ' '); EXPECT_THROW(LinkCreateTemplate lct(link_template), invalid_argument); } @@ -267,7 +284,6 @@ TEST(LinkCreateTemplate, TestInvalidNode) { EXPECT_THROW(LinkCreateTemplate lct(link_template), invalid_argument); } - TEST(Link, TestLink) { vector link_template = split("LINK_CREATE Similarity 2 0 VARIABLE V1 VARIABLE V2", ' '); HandlesAnswer* query_answer = new HandlesAnswer(); diff --git a/src/tests/cpp/link_template_test.cc b/src/tests/cpp/link_template_test.cc index fa670a8..27d119e 100644 --- a/src/tests/cpp/link_template_test.cc +++ b/src/tests/cpp/link_template_test.cc @@ -1,17 +1,16 @@ #include -#include "gtest/gtest.h" -#include "QueryNode.h" -#include "LinkTemplate.h" #include "AtomDBSingleton.h" -#include "test_utils.h" #include "HandlesAnswer.h" +#include "LinkTemplate.h" +#include "QueryNode.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace query_engine; using namespace query_element; TEST(LinkTemplate, basics) { - setenv("DAS_REDIS_HOSTNAME", "localhost", 1); setenv("DAS_REDIS_PORT", "29000", 1); setenv("DAS_USE_REDIS_CLUSTER", "false", 1); @@ -36,19 +35,19 @@ TEST(LinkTemplate, basics) { LinkTemplate<3> link_template1("Expression", {&similarity, &human, &v1}); link_template1.subsequent_id = server_node_id; link_template1.setup_buffers(); - //link_template1.fetch_links(); + // link_template1.fetch_links(); Utils::sleep(1000); - string monkey_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"monkey\"")); - string chimp_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"chimp\"")); - string ent_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"ent\"")); + string monkey_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"monkey\"")); + string chimp_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"chimp\"")); + string ent_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"ent\"")); bool monkey_flag = false; bool chimp_flag = false; bool ent_flag = false; - HandlesAnswer *query_answer; + HandlesAnswer* query_answer; while ((query_answer = dynamic_cast(server_node.pop_query_answer())) != NULL) { string var = string(query_answer->assignment.get("v1")); - //EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); + // EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); if (var == monkey_handle) { // TODO: perform extra checks monkey_flag = true; diff --git a/src/tests/cpp/message_broker_test.cc b/src/tests/cpp/message_broker_test.cc index eec7c09..369ca96 100644 --- a/src/tests/cpp/message_broker_test.cc +++ b/src/tests/cpp/message_broker_test.cc @@ -1,21 +1,20 @@ -#include "gtest/gtest.h" #include "MessageBroker.h" +#include "gtest/gtest.h" using namespace distributed_algorithm_node; class MessageFactoryTest : public MessageFactory { - shared_ptr message_factory(string &command, vector &args) { + shared_ptr message_factory(string& command, vector& args) { return shared_ptr{}; } }; TEST(MessageBroker, basics) { - try { MessageBroker::factory((MessageBrokerType) -1, NULL, ""); FAIL() << "Expected exception"; - } catch(std::runtime_error const &error) { - } catch(...) { + } catch (std::runtime_error const& error) { + } catch (...) { FAIL() << "Expected std::runtime_error"; } @@ -23,8 +22,8 @@ TEST(MessageBroker, basics) { shared_ptr message_broker_ram = MessageBroker::factory(MessageBrokerType::RAM, shared_ptr{}, ""); FAIL() << "Expected exception"; - } catch(std::runtime_error const &error) { - } catch(...) { + } catch (std::runtime_error const& error) { + } catch (...) { FAIL() << "Expected std::runtime_error"; } @@ -32,14 +31,14 @@ TEST(MessageBroker, basics) { shared_ptr message_broke_grpc = MessageBroker::factory(MessageBrokerType::GRPC, shared_ptr{}, ""); FAIL() << "Expected exception"; - } catch(std::runtime_error const &error) { - } catch(...) { + } catch (std::runtime_error const& error) { + } catch (...) { FAIL() << "Expected std::runtime_error"; } - shared_ptr message_broker_ram = - MessageBroker::factory(MessageBrokerType::RAM, shared_ptr(new MessageFactoryTest()), ""); + shared_ptr message_broker_ram = MessageBroker::factory( + MessageBrokerType::RAM, shared_ptr(new MessageFactoryTest()), ""); - shared_ptr message_broker_grpc = - MessageBroker::factory(MessageBrokerType::GRPC, shared_ptr(new MessageFactoryTest()), ""); + shared_ptr message_broker_grpc = MessageBroker::factory( + MessageBrokerType::GRPC, shared_ptr(new MessageFactoryTest()), ""); } diff --git a/src/tests/cpp/nested_link_template_test.cc b/src/tests/cpp/nested_link_template_test.cc index 0beff33..5d147f5 100644 --- a/src/tests/cpp/nested_link_template_test.cc +++ b/src/tests/cpp/nested_link_template_test.cc @@ -1,18 +1,17 @@ #include -#include "gtest/gtest.h" -#include "QueryNode.h" #include "AtomDB.h" -#include "LinkTemplate.h" #include "AtomDBSingleton.h" -#include "test_utils.h" #include "HandlesAnswer.h" +#include "LinkTemplate.h" +#include "QueryNode.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace query_engine; using namespace query_element; TEST(LinkTemplate, basics) { - setenv("DAS_REDIS_HOSTNAME", "localhost", 1); setenv("DAS_REDIS_PORT", "29000", 1); setenv("DAS_USE_REDIS_CLUSTER", "false", 1); @@ -36,9 +35,9 @@ TEST(LinkTemplate, basics) { Iterator iterator(&outter_template); - HandlesAnswer *query_answer; + HandlesAnswer* query_answer; unsigned int count = 0; - while (! iterator.finished()) { + while (!iterator.finished()) { if ((query_answer = dynamic_cast(iterator.pop())) == NULL) { Utils::sleep(); } else { @@ -50,7 +49,6 @@ TEST(LinkTemplate, basics) { } TEST(LinkTemplate, nested_variables) { - string expression = "Expression"; string symbol = "Symbol"; @@ -68,13 +66,13 @@ TEST(LinkTemplate, nested_variables) { Iterator iterator(&and_operator); - HandlesAnswer *query_answer; + HandlesAnswer* query_answer; unsigned int count = 0; - while (! iterator.finished()) { + while (!iterator.finished()) { if ((query_answer = dynamic_cast(iterator.pop())) == NULL) { Utils::sleep(); } else { - //EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); + // EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); count++; } } diff --git a/src/tests/cpp/query_node_test.cc b/src/tests/cpp/query_node_test.cc index c3c308e..60931c1 100644 --- a/src/tests/cpp/query_node_test.cc +++ b/src/tests/cpp/query_node_test.cc @@ -1,14 +1,12 @@ -#include "gtest/gtest.h" - -#include "Utils.h" -#include "QueryNode.h" #include "HandlesAnswer.h" +#include "QueryNode.h" +#include "Utils.h" +#include "gtest/gtest.h" using namespace commons; using namespace query_node; TEST(QueryNode, basics) { - string server_id = "server"; string client1_id = "client1"; string client2_id = "client2"; @@ -24,15 +22,15 @@ TEST(QueryNode, basics) { EXPECT_TRUE(client2.is_query_answers_empty()); EXPECT_FALSE(client2.is_query_answers_finished()); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 0); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 0); - client1.add_query_answer((QueryAnswer *) 1); - client1.add_query_answer((QueryAnswer *) 2); + client1.add_query_answer((QueryAnswer*) 1); + client1.add_query_answer((QueryAnswer*) 2); Utils::sleep(1000); - client2.add_query_answer((QueryAnswer *) 3); - client2.add_query_answer((QueryAnswer *) 4); + client2.add_query_answer((QueryAnswer*) 3); + client2.add_query_answer((QueryAnswer*) 4); Utils::sleep(1000); - client1.add_query_answer((QueryAnswer *) 5); + client1.add_query_answer((QueryAnswer*) 5); Utils::sleep(1000); EXPECT_FALSE(server.is_query_answers_empty()); @@ -53,12 +51,12 @@ TEST(QueryNode, basics) { EXPECT_TRUE(client2.is_query_answers_empty()); EXPECT_TRUE(client2.is_query_answers_finished()); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 1); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 2); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 3); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 4); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 5); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 0); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 1); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 2); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 3); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 4); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 5); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 0); EXPECT_TRUE(server.is_query_answers_empty()); EXPECT_TRUE(server.is_query_answers_finished()); diff --git a/src/tests/cpp/request_selector_test.cc b/src/tests/cpp/request_selector_test.cc index 2376d5d..e04d39b 100644 --- a/src/tests/cpp/request_selector_test.cc +++ b/src/tests/cpp/request_selector_test.cc @@ -1,36 +1,26 @@ -#include "gtest/gtest.h" - -#include "Utils.h" -#include "SharedQueue.h" #include "RequestSelector.h" +#include "SharedQueue.h" +#include "Utils.h" +#include "gtest/gtest.h" using namespace attention_broker_server; class TestMessage { - public: - int message; - TestMessage(int n) { - message = n; - } + public: + int message; + TestMessage(int n) { message = n; } }; TEST(RequestSelectorTest, even_thread_count) { - - SharedQueue *stimulus = new SharedQueue(1); - SharedQueue *correlation = new SharedQueue(1); + SharedQueue* stimulus = new SharedQueue(1); + SharedQueue* correlation = new SharedQueue(1); - RequestSelector *selector0 = RequestSelector::factory( - SelectorType::EVEN_THREAD_COUNT, - 0, - stimulus, - correlation); - RequestSelector *selector1 = RequestSelector::factory( - SelectorType::EVEN_THREAD_COUNT, - 1, - stimulus, - correlation); + RequestSelector* selector0 = + RequestSelector::factory(SelectorType::EVEN_THREAD_COUNT, 0, stimulus, correlation); + RequestSelector* selector1 = + RequestSelector::factory(SelectorType::EVEN_THREAD_COUNT, 1, stimulus, correlation); - pair request; + pair request; for (int i = 0; i < 1000; i++) { if (Utils::flip_coin()) { request = selector0->next(); diff --git a/src/tests/cpp/shared_queue_test.cc b/src/tests/cpp/shared_queue_test.cc index 651e37d..b9f670c 100644 --- a/src/tests/cpp/shared_queue_test.cc +++ b/src/tests/cpp/shared_queue_test.cc @@ -1,74 +1,63 @@ -#include "gtest/gtest.h" - #include "AttentionBrokerServer.h" +#include "gtest/gtest.h" using namespace attention_broker_server; -class TestSharedQueue: public SharedQueue { - public: - TestSharedQueue(unsigned int n) : SharedQueue(n) { - } - unsigned int test_current_size() { - return current_size(); - } - unsigned int test_current_start() { - return current_start(); - } - unsigned int test_current_end() { - return current_end(); - } +class TestSharedQueue : public SharedQueue { + public: + TestSharedQueue(unsigned int n) : SharedQueue(n) {} + unsigned int test_current_size() { return current_size(); } + unsigned int test_current_start() { return current_start(); } + unsigned int test_current_end() { return current_end(); } }; class TestMessage { - public: - int message; - TestMessage(int n) { - message = n; - } + public: + int message; + TestMessage(int n) { message = n; } }; TEST(SharedQueueTest, basics) { - dasproto::Empty empty; dasproto::Ack ack; TestSharedQueue q1((unsigned int) 5); EXPECT_TRUE(q1.test_current_size() == 5); - q1.enqueue((void *) "1"); - EXPECT_EQ((char *) q1.dequeue(), "1"); - q1.enqueue((void *) "2"); - q1.enqueue((void *) "3"); - q1.enqueue((void *) "4"); - q1.enqueue((void *) "5"); + q1.enqueue((void*) "1"); + EXPECT_EQ((char*) q1.dequeue(), "1"); + q1.enqueue((void*) "2"); + q1.enqueue((void*) "3"); + q1.enqueue((void*) "4"); + q1.enqueue((void*) "5"); EXPECT_TRUE(q1.test_current_size() == 5); - EXPECT_EQ((char *) q1.dequeue(), "2"); - q1.enqueue((void *) "6"); - q1.enqueue((void *) "7"); + EXPECT_EQ((char*) q1.dequeue(), "2"); + q1.enqueue((void*) "6"); + q1.enqueue((void*) "7"); EXPECT_TRUE(q1.test_current_size() == 5); - EXPECT_EQ((char *) q1.dequeue(), "3"); - q1.enqueue((void *) "8"); - EXPECT_EQ((char *) q1.dequeue(), "4"); - q1.enqueue((void *) "9"); - EXPECT_EQ((char *) q1.dequeue(), "5"); - q1.enqueue((void *) "10"); + EXPECT_EQ((char*) q1.dequeue(), "3"); + q1.enqueue((void*) "8"); + EXPECT_EQ((char*) q1.dequeue(), "4"); + q1.enqueue((void*) "9"); + EXPECT_EQ((char*) q1.dequeue(), "5"); + q1.enqueue((void*) "10"); EXPECT_TRUE(q1.test_current_size() == 5); - EXPECT_EQ((char *) q1.dequeue(), "6"); - EXPECT_EQ((char *) q1.dequeue(), "7"); - q1.enqueue((void *) "11"); - q1.enqueue((void *) "12"); + EXPECT_EQ((char*) q1.dequeue(), "6"); + EXPECT_EQ((char*) q1.dequeue(), "7"); + q1.enqueue((void*) "11"); + q1.enqueue((void*) "12"); EXPECT_TRUE(q1.test_current_size() == 5); EXPECT_TRUE(q1.test_current_start() == 2); EXPECT_TRUE(q1.test_current_end() == 2); - q1.enqueue((void *) "13"); + q1.enqueue((void*) "13"); EXPECT_TRUE(q1.test_current_size() == 10); EXPECT_TRUE(q1.test_current_start() == 0); EXPECT_TRUE(q1.test_current_end() == 6); - q1.enqueue((void *) "14"); - EXPECT_EQ((char *) q1.dequeue(), "8"); - EXPECT_EQ((char *) q1.dequeue(), "9"); - EXPECT_EQ((char *) q1.dequeue(), "10"); - EXPECT_EQ((char *) q1.dequeue(), "11"); - EXPECT_EQ((char *) q1.dequeue(), "12"); - EXPECT_EQ((char *) q1.dequeue(), "13"); - EXPECT_EQ((char *) q1.dequeue(), "14"); + q1.enqueue((void*) "14"); + EXPECT_EQ((char*) q1.dequeue(), "8"); + EXPECT_EQ((char*) q1.dequeue(), "9"); + EXPECT_EQ((char*) q1.dequeue(), "10"); + EXPECT_EQ((char*) q1.dequeue(), "11"); + EXPECT_EQ((char*) q1.dequeue(), "12"); + EXPECT_EQ((char*) q1.dequeue(), "13"); + EXPECT_EQ((char*) q1.dequeue(), "14"); } diff --git a/src/tests/cpp/stimulus_spreader_test.cc b/src/tests/cpp/stimulus_spreader_test.cc index 6e99f89..5b2b778 100644 --- a/src/tests/cpp/stimulus_spreader_test.cc +++ b/src/tests/cpp/stimulus_spreader_test.cc @@ -1,16 +1,16 @@ -#include #include +#include -#include "gtest/gtest.h" -#include "common.pb.h" -#include "attention_broker.grpc.pb.h" -#include "attention_broker.pb.h" -#include "test_utils.h" -#include "expression_hasher.h" #include "AttentionBrokerServer.h" #include "HebbianNetwork.h" #include "HebbianNetworkUpdater.h" #include "StimulusSpreader.h" +#include "attention_broker.grpc.pb.h" +#include "attention_broker.pb.h" +#include "common.pb.h" +#include "expression_hasher.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace attention_broker_server; @@ -20,18 +20,17 @@ bool importance_equals(ImportanceType importance, double v2) { } TEST(TokenSpreader, distribute_wages) { - unsigned int num_tests = 10000; unsigned int total_nodes = 100; - TokenSpreader *spreader; + TokenSpreader* spreader; ImportanceType tokens_to_spread; - dasproto::HandleCount *request; + dasproto::HandleCount* request; TokenSpreader::StimuliData data; for (unsigned int i = 0; i < num_tests; i++) { - string *handles = build_handle_space(total_nodes); - spreader = (TokenSpreader *) StimulusSpreader::factory(StimulusSpreaderType::TOKEN); + string* handles = build_handle_space(total_nodes); + spreader = (TokenSpreader*) StimulusSpreader::factory(StimulusSpreaderType::TOKEN); tokens_to_spread = 1.0; request = new dasproto::HandleCount(); @@ -44,11 +43,21 @@ TEST(TokenSpreader, distribute_wages) { data.importance_changes = new HandleTrie(HANDLE_HASH_SIZE - 1); spreader->distribute_wages(request, tokens_to_spread, &data); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[0]))->wages, 0.250)); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[1]))->wages, 0.125)); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[2]))->wages, 0.250)); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[3]))->wages, 0.125)); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[4]))->wages, 0.250)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[0]))->wages, + 0.250)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[1]))->wages, + 0.125)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[2]))->wages, + 0.250)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[3]))->wages, + 0.125)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[4]))->wages, + 0.250)); EXPECT_TRUE(data.importance_changes->lookup(handles[5]) == NULL); EXPECT_TRUE(data.importance_changes->lookup(handles[6]) == NULL); EXPECT_TRUE(data.importance_changes->lookup(handles[7]) == NULL); @@ -59,12 +68,11 @@ TEST(TokenSpreader, distribute_wages) { } } -static HebbianNetwork *build_test_network(string *handles) { - - HebbianNetwork *network = new HebbianNetwork(); - dasproto::HandleList *request; - ExactCountHebbianUpdater *updater = \ - (ExactCountHebbianUpdater *) HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); +static HebbianNetwork* build_test_network(string* handles) { + HebbianNetwork* network = new HebbianNetwork(); + dasproto::HandleList* request; + ExactCountHebbianUpdater* updater = (ExactCountHebbianUpdater*) HebbianNetworkUpdater::factory( + HebbianNetworkUpdaterType::EXACT_COUNT); request = new dasproto::HandleList(); request->set_hebbian_network((unsigned long) network); @@ -86,7 +94,6 @@ static HebbianNetwork *build_test_network(string *handles) { } TEST(TokenSpreader, spread_stimuli) { - // -------------------------------------------------------------------- // NOTE TO REVIEWER: I left debug messages because this code extremely // error prone and difficult to debug. Probably we'll @@ -95,12 +102,12 @@ TEST(TokenSpreader, spread_stimuli) { // -------------------------------------------------------------------- // Build and check network - string *handles = build_handle_space(6, true); + string* handles = build_handle_space(6, true); for (unsigned int i = 0; i < 6; i++) { cout << i << ": " << handles[i] << endl; } - HebbianNetwork *network = build_test_network(handles); + HebbianNetwork* network = build_test_network(handles); unsigned int expected[6][6] = { {0, 1, 1, 1, 0, 0}, @@ -118,7 +125,8 @@ TEST(TokenSpreader, spread_stimuli) { EXPECT_TRUE(network->get_node_count(handles[i]) == 1); } for (unsigned int j = 0; j < 6; j++) { - cout << i << ", " << j << ": " << expected[i][j] << " " << network->get_asymmetric_edge_count(handles[i], handles[j]) << endl; + cout << i << ", " << j << ": " << expected[i][j] << " " + << network->get_asymmetric_edge_count(handles[i], handles[j]) << endl; EXPECT_TRUE(network->get_asymmetric_edge_count(handles[i], handles[j]) == expected[i][j]); } } @@ -126,9 +134,8 @@ TEST(TokenSpreader, spread_stimuli) { // ---------------------------------------------------------- // Build and process simulus spreading request - dasproto::HandleCount *request; - TokenSpreader *spreader = \ - (TokenSpreader *) StimulusSpreader::factory(StimulusSpreaderType::TOKEN); + dasproto::HandleCount* request; + TokenSpreader* spreader = (TokenSpreader*) StimulusSpreader::factory(StimulusSpreaderType::TOKEN); request = new dasproto::HandleCount(); request->set_hebbian_network((unsigned long) network); diff --git a/src/tests/cpp/test_utils.cc b/src/tests/cpp/test_utils.cc index 4c734e9..54f01df 100644 --- a/src/tests/cpp/test_utils.cc +++ b/src/tests/cpp/test_utils.cc @@ -1,9 +1,11 @@ -#include "expression_hasher.h" -#include "Utils.h" #include "test_utils.h" + #include #include +#include "Utils.h" +#include "expression_hasher.h" + static char REVERSE_TLB[16] = { '0', '1', @@ -23,9 +25,7 @@ static char REVERSE_TLB[16] = { 'f', }; -double random_importance() { - return ((double) rand()) / RAND_MAX; -} +double random_importance() { return ((double) rand()) / RAND_MAX; } string random_handle() { char buffer[HANDLE_HASH_SIZE]; @@ -38,9 +38,7 @@ string random_handle() { return s; } -string sequential_label(unsigned int &count, string prefix) { - return prefix + std::to_string(count++); -} +string sequential_label(unsigned int& count, string prefix) { return prefix + std::to_string(count++); } string prefixed_random_handle(string prefix) { char buffer[HANDLE_HASH_SIZE]; @@ -57,12 +55,10 @@ string prefixed_random_handle(string prefix) { return s; } -static bool str_comp(string &a, string &b) { - return a.compare(b) < 0; -} +static bool str_comp(string& a, string& b) { return a.compare(b) < 0; } -string *build_handle_space(unsigned int size, bool sort) { - string *answer = new string[size]; +string* build_handle_space(unsigned int size, bool sort) { + string* answer = new string[size]; for (unsigned int i = 0; i < size; i++) { answer[i] = random_handle(); } @@ -72,6 +68,4 @@ string *build_handle_space(unsigned int size, bool sort) { return answer; } -bool double_equals(double v1, double v2) { - return fabs(v2 - v1) < 0.001; -} +bool double_equals(double v1, double v2) { return fabs(v2 - v1) < 0.001; } diff --git a/src/tests/cpp/test_utils.h b/src/tests/cpp/test_utils.h index 2ba9d15..6705323 100644 --- a/src/tests/cpp/test_utils.h +++ b/src/tests/cpp/test_utils.h @@ -1,16 +1,17 @@ #ifndef _ATTENTION_BROKER_SERVER_TESTS_TESTUTILS #define _ATTENTION_BROKER_SERVER_TESTS_TESTUTILS -#include #include +#include + using namespace std; double random_importance(); string random_handle(); -string sequential_label(unsigned int &count, string prefix = "v"); +string sequential_label(unsigned int& count, string prefix = "v"); string prefixed_random_handle(string prefix); -string *build_handle_space(unsigned int size, bool sort=false); +string* build_handle_space(unsigned int size, bool sort = false); bool double_equals(double v1, double v2); #endif diff --git a/src/tests/cpp/worker_threads_test.cc b/src/tests/cpp/worker_threads_test.cc index e850b89..ec8f7f7 100644 --- a/src/tests/cpp/worker_threads_test.cc +++ b/src/tests/cpp/worker_threads_test.cc @@ -1,41 +1,35 @@ #include #include -#include "gtest/gtest.h" -#include "common.pb.h" +#include "HebbianNetwork.h" +#include "SharedQueue.h" +#include "Utils.h" +#include "WorkerThreads.h" #include "attention_broker.grpc.pb.h" #include "attention_broker.pb.h" - -#include "Utils.h" +#include "common.pb.h" +#include "gtest/gtest.h" #include "test_utils.h" -#include "SharedQueue.h" -#include "WorkerThreads.h" -#include "HebbianNetwork.h" using namespace attention_broker_server; -class TestSharedQueue: public SharedQueue { - public: - TestSharedQueue() : SharedQueue() { - } - unsigned int test_current_count() { - return current_count(); - } +class TestSharedQueue : public SharedQueue { + public: + TestSharedQueue() : SharedQueue() {} + unsigned int test_current_count() { return current_count(); } }; - TEST(WorkerThreads, basics) { - - dasproto::HandleCount *handle_count; - dasproto::HandleList *handle_list; + dasproto::HandleCount* handle_count; + dasproto::HandleList* handle_list; unsigned int num_requests = 1000000; unsigned int wait_for_threads_ms = 500; - for (double stimulus_prob: {0.0, 0.25, 0.5, 0.75, 1.0}) { - TestSharedQueue *stimulus = new TestSharedQueue(); - TestSharedQueue *correlation = new TestSharedQueue(); - WorkerThreads *pool = new WorkerThreads(stimulus, correlation); + for (double stimulus_prob : {0.0, 0.25, 0.5, 0.75, 1.0}) { + TestSharedQueue* stimulus = new TestSharedQueue(); + TestSharedQueue* correlation = new TestSharedQueue(); + WorkerThreads* pool = new WorkerThreads(stimulus, correlation); for (unsigned int i = 0; i < num_requests; i++) { if (Utils::flip_coin(stimulus_prob)) { handle_count = new dasproto::HandleCount(); @@ -57,15 +51,14 @@ TEST(WorkerThreads, basics) { } TEST(WorkerThreads, hebbian_network_updater_basics) { - - dasproto::HandleList *handle_list; + dasproto::HandleList* handle_list; map node_count; map edge_count; HebbianNetwork network; - TestSharedQueue *stimulus = new TestSharedQueue(); - TestSharedQueue *correlation = new TestSharedQueue(); - WorkerThreads *pool = new WorkerThreads(stimulus, correlation); + TestSharedQueue* stimulus = new TestSharedQueue(); + TestSharedQueue* correlation = new TestSharedQueue(); + WorkerThreads* pool = new WorkerThreads(stimulus, correlation); handle_list = new dasproto::HandleList(); string h1 = random_handle(); @@ -146,25 +139,23 @@ TEST(WorkerThreads, hebbian_network_updater_basics) { } TEST(WorkerThreads, hebbian_network_updater_stress) { - - #define HANDLE_SPACE_SIZE ((unsigned int) 100) +#define HANDLE_SPACE_SIZE ((unsigned int) 100) unsigned int num_requests = 10; unsigned int max_handles_per_request = 10; unsigned int wait_for_worker_threads_ms = 3000; - - dasproto::HandleList *handle_list; + dasproto::HandleList* handle_list; string handles[HANDLE_SPACE_SIZE]; map node_count; map edge_count; - HebbianNetwork *network = new HebbianNetwork(); + HebbianNetwork* network = new HebbianNetwork(); for (unsigned int i = 0; i < HANDLE_SPACE_SIZE; i++) { handles[i] = random_handle(); } - TestSharedQueue *stimulus = new TestSharedQueue(); - TestSharedQueue *correlation = new TestSharedQueue(); - WorkerThreads *pool = new WorkerThreads(stimulus, correlation); + TestSharedQueue* stimulus = new TestSharedQueue(); + TestSharedQueue* correlation = new TestSharedQueue(); + WorkerThreads* pool = new WorkerThreads(stimulus, correlation); for (unsigned int i = 0; i < num_requests; i++) { handle_list = new dasproto::HandleList(); unsigned int num_handles = (rand() % (max_handles_per_request - 1)) + 2; @@ -176,8 +167,8 @@ TEST(WorkerThreads, hebbian_network_updater_stress) { } node_count[h] = node_count[h] + 1; } - for (const string &h1: handle_list->list()) { - for (const string &h2: handle_list->list()) { + for (const string& h1 : handle_list->list()) { + for (const string& h2 : handle_list->list()) { string composite; if (h1.compare(h2) < 0) { composite = h1 + h2; diff --git a/src/tools/format/BUILD.bazel b/src/tools/format/BUILD.bazel index 08f130f..5f45186 100644 --- a/src/tools/format/BUILD.bazel +++ b/src/tools/format/BUILD.bazel @@ -3,11 +3,14 @@ load("@aspect_rules_lint//format:defs.bzl", "format_multirun") format_multirun( name = "format", - # cc = "@llvm_toolchain_llvm//:bin/clang-format", + cc = "@llvm_toolchain_llvm//:bin/clang-format", python = "@aspect_rules_lint//format:ruff", - disable_git_attribute_checks=True, - # starlark = "@buildifier_prebuild//:buildifier" # TODO: ADD rules for yaml, markdown, rust, c + # starlark = "@buildifier_prebuild//:buildifier" + # rust = "@rules_rust//tools/upstream_wrapper:rustfmt", + # yaml = "@aspect_rules_lint//format:yamlfmt", + + disable_git_attribute_checks=True, visibility = ["//visibility:public"], ) diff --git a/src/tools/lint/BUILD b/src/tools/lint/BUILD index e69de29..89c2d01 100644 --- a/src/tools/lint/BUILD +++ b/src/tools/lint/BUILD @@ -0,0 +1,14 @@ +load("@bazel_skylib//rules:native_binary.bzl", "native_binary") + +native_binary( + name = "clang_tidy", + src = select( + { + "@bazel_tools//src/conditions:linux_x86_64": "@llvm_toolchain_llvm//:bin/clang-tidy", + "@bazel_tools//src/conditions:linux_aarch64": "@llvm_toolchain_llvm//:bin/clang-tidy", + "@bazel_tools//src/conditions:darwin_x86_64": "@llvm_toolchain_llvm//:bin/clang-tidy", + "@bazel_tools//src/conditions:darwin_arm64": "@llvm_toolchain_llvm//:bin/clang-tidy", + }, + ), + out = "clang_tidy", +) diff --git a/src/tools/lint/linters.bzl b/src/tools/lint/linters.bzl index 2265c8b..4acfadb 100644 --- a/src/tools/lint/linters.bzl +++ b/src/tools/lint/linters.bzl @@ -1,6 +1,17 @@ load("@aspect_rules_lint//lint:lint_test.bzl", "lint_test") +load("@aspect_rules_lint//lint:clang_tidy.bzl", "lint_clang_tidy_aspect") load("@aspect_rules_lint//lint:ruff.bzl", "lint_ruff_aspect") +clang_tidy = lint_clang_tidy_aspect( + binary = "@@//tools/lint:clang_tidy", + global_config = "@@//:.clang-tidy", + lint_target_headers = True, + angle_includes_are_system = False, + verbose = False, +) + +clang_tidy_test = lint_test(aspect = clang_tidy) + ruff = lint_ruff_aspect( binary = "@multitool//tools/ruff", configs = [ From cef775997064b2df8349b76bd4f66c593ba14f17 Mon Sep 17 00:00:00 2001 From: Pedro Costa Date: Fri, 21 Feb 2025 20:02:33 +0000 Subject: [PATCH 2/5] revert: changes to clang-format --- .clang-format | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index cb6fd0c..eac44b1 100644 --- a/.clang-format +++ b/.clang-format @@ -212,9 +212,9 @@ StatementAttributeLikeMacros: StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION -TabWidth: 8 +TabWidth: 4 UseCRLF: false -UseTab: Always +UseTab: Never WhitespaceSensitiveMacros: - STRINGIZE - PP_STRINGIZE From fd591513578ff7f234a4aa572b34a76e6228c315 Mon Sep 17 00:00:00 2001 From: Pedro Costa Date: Fri, 21 Feb 2025 20:35:48 +0000 Subject: [PATCH 3/5] task: remove das-proto from Dockerfile --- src/docker/Dockerfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/docker/Dockerfile b/src/docker/Dockerfile index 36955bc..6a72193 100644 --- a/src/docker/Dockerfile +++ b/src/docker/Dockerfile @@ -32,11 +32,6 @@ RUN cd ${THIRD_PARTY} \ && ln -s ${THIRD_PARTY} ${DAS_DIR}/src/3rd-party \ && mv bazelisk ${BAZEL_DIR} -# TODO: integrate this to bazel build (https://github.com/singnet/das/issues/197) -ADD https://raw.githubusercontent.com/singnet/das-query-engine/master/proto/attention_broker.proto ${PROTO_DIR} -ADD https://raw.githubusercontent.com/singnet/das-query-engine/master/proto/common.proto ${PROTO_DIR} -ADD https://raw.githubusercontent.com/singnet/das-query-engine/master/proto/echo.proto ${PROTO_DIR} - ################################################################################ # To be removed when AtomDB is properly integrated # Redis client From 901d4db4942c0996c5e775d8887051d1c67d00ac Mon Sep 17 00:00:00 2001 From: Pedro Costa Date: Fri, 21 Feb 2025 20:02:01 +0000 Subject: [PATCH 4/5] task: clang-format cpp code --- .clang-format | 4 +- src/.aspect/cli/config.yaml | 1 + src/.clang-format | 225 ++++++++++++++ src/BUILD | 1 + src/MODULE.bazel | 13 + src/MODULE.bazel.lock | 83 +++++ src/attention_broker/AttentionBrokerServer.cc | 73 ++--- src/attention_broker/AttentionBrokerServer.h | 254 ++++++++------- src/attention_broker/HandleTrie.cc | 100 +++--- src/attention_broker/HandleTrie.h | 87 +++--- src/attention_broker/HebbianNetwork.cc | 89 +++--- src/attention_broker/HebbianNetwork.h | 139 ++++----- src/attention_broker/HebbianNetworkUpdater.cc | 39 ++- src/attention_broker/HebbianNetworkUpdater.h | 95 +++--- src/attention_broker/RequestSelector.cc | 50 ++- src/attention_broker/RequestSelector.h | 73 ++--- src/attention_broker/StimulusSpreader.cc | 120 ++++--- src/attention_broker/StimulusSpreader.h | 150 ++++----- src/attention_broker/WorkerThreads.cc | 60 ++-- src/attention_broker/WorkerThreads.h | 55 ++-- src/commons/SharedQueue.cc | 30 +- src/commons/SharedQueue.h | 37 ++- src/commons/Utils.cc | 44 +-- src/commons/Utils.h | 37 ++- .../DistributedAlgorithmNode.cc | 62 ++-- .../DistributedAlgorithmNode.h | 129 ++++---- .../LeadershipBroker.cc | 36 +-- .../LeadershipBroker.h | 50 ++- src/distributed_algorithm_node/Message.cc | 14 +- src/distributed_algorithm_node/Message.h | 60 ++-- .../MessageBroker.cc | 199 ++++++------ .../MessageBroker.h | 254 ++++++++------- src/docker/Dockerfile | 2 +- src/hasher/expression_hasher.cc | 27 +- src/hasher/expression_hasher.h | 12 +- .../atom_db_publicist.h | 10 +- src/hyperon_das_atomdb_cpp/bind_helpers.h | 35 ++- .../hyperon_das_atomdb_cpp_bind.cc | 34 +- src/hyperon_das_atomdb_cpp_lib/database.cc | 6 +- src/hyperon_das_atomdb_cpp_lib/database.h | 190 +++++++----- .../document_types.h | 167 +++++----- src/hyperon_das_atomdb_cpp_lib/exceptions.h | 42 +-- .../expression_hasher.h | 57 ++-- src/hyperon_das_atomdb_cpp_lib/patterns.h | 27 +- src/hyperon_das_atomdb_cpp_lib/ram_only.cc | 6 +- src/hyperon_das_atomdb_cpp_lib/ram_only.h | 98 +++--- src/hyperon_das_atomdb_cpp_lib/type_aliases.h | 32 +- src/hyperon_das_node/hyperon_das_node_ext.cc | 140 ++++----- src/inference_agent/inference_agent.h | 15 +- src/inference_agent/inference_node.h | 4 - src/inference_agent/inference_request.h | 2 - .../das_link_creation_node.cc | 10 +- .../das_link_creation_node.h | 5 +- src/link_creation_agent/link.cc | 5 +- src/link_creation_agent/link.h | 95 +++--- .../link_create_template.h | 22 +- src/link_creation_agent/link_creation_agent.h | 30 +- src/link_creation_agent/queue.h | 16 +- src/main/attention_broker_main.cc | 20 +- src/main/inference_agent_main.cc | 1 - src/main/link_creation_agent_client_main.cc | 1 - src/main/link_creation_agent_main.cc | 27 +- src/main/link_creation_engine_main.cc | 119 ++++--- src/main/query_client_main.cc | 23 +- src/main/query_engine_main.cc | 13 +- src/main/word_query_main.cc | 79 +++-- src/query_engine/AtomDB.cc | 73 +++-- src/query_engine/AtomDB.h | 58 ++-- src/query_engine/AtomDBAPITypes.cc | 69 +++-- src/query_engine/AtomDBAPITypes.h | 86 +++--- src/query_engine/AtomDBSingleton.cc | 14 +- src/query_engine/AtomDBSingleton.h | 18 +- src/query_engine/CountAnswer.h | 6 +- src/query_engine/DASNode.cc | 23 +- src/query_engine/HandlesAnswer.cc | 105 +++---- src/query_engine/HandlesAnswer.h | 272 ++++++++-------- src/query_engine/StarNode.cc | 21 +- src/query_engine/StarNode.h | 45 ++- .../answer_processor/AttentionBrokerUpdater.h | 18 +- src/query_engine/query_element/And.h | 116 +++---- src/query_engine/query_element/Iterator.cc | 27 +- src/query_engine/query_element/Iterator.h | 36 ++- src/query_engine/query_element/LinkTemplate.h | 40 ++- src/query_engine/query_element/Operator.h | 29 +- src/query_engine/query_element/Or.h | 88 +++--- .../query_element/QueryElement.cc | 3 +- src/query_engine/query_element/QueryElement.h | 107 ++++--- .../query_element/RemoteIterator.h | 56 ++-- src/query_engine/query_element/RemoteSink.h | 15 +- src/query_engine/query_element/Sink.cc | 10 +- src/query_engine/query_element/Sink.h | 56 ++-- src/query_engine/query_element/Source.h | 20 +- src/query_engine/query_element/Terminal.h | 88 +++--- src/scripts/bazel.sh | 24 +- src/scripts/build.sh | 24 +- src/tests/cpp/and_operator_test.cc | 153 +++++---- src/tests/cpp/attention_broker_server_test.cc | 22 +- src/tests/cpp/das_node_test.cc | 126 ++++---- .../cpp/distributed_algorithm_node_test.cc | 96 ++---- src/tests/cpp/handle_trie_test.cc | 292 +++++++++--------- src/tests/cpp/handles_answer_test.cc | 14 +- src/tests/cpp/hebbian_network_test.cc | 50 ++- src/tests/cpp/hebbian_network_updater_test.cc | 22 +- src/tests/cpp/iterator_test.cc | 32 +- src/tests/cpp/leadership_broker_test.cc | 9 +- src/tests/cpp/link_creation_agent_test.cc | 52 ++-- src/tests/cpp/link_template_test.cc | 21 +- src/tests/cpp/message_broker_test.cc | 25 +- src/tests/cpp/nested_link_template_test.cc | 20 +- src/tests/cpp/query_node_test.cc | 32 +- src/tests/cpp/request_selector_test.cc | 36 +-- src/tests/cpp/shared_queue_test.cc | 87 +++--- src/tests/cpp/stimulus_spreader_test.cc | 67 ++-- src/tests/cpp/test_utils.cc | 26 +- src/tests/cpp/test_utils.h | 7 +- src/tests/cpp/worker_threads_test.cc | 65 ++-- src/tools/format/BUILD.bazel | 9 +- src/tools/lint/BUILD | 14 + src/tools/lint/linters.bzl | 11 + 119 files changed, 3545 insertions(+), 3325 deletions(-) create mode 100644 src/.clang-format diff --git a/.clang-format b/.clang-format index eac44b1..cb6fd0c 100644 --- a/.clang-format +++ b/.clang-format @@ -212,9 +212,9 @@ StatementAttributeLikeMacros: StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION -TabWidth: 4 +TabWidth: 8 UseCRLF: false -UseTab: Never +UseTab: Always WhitespaceSensitiveMacros: - STRINGIZE - PP_STRINGIZE diff --git a/src/.aspect/cli/config.yaml b/src/.aspect/cli/config.yaml index 642f7cc..5e360bc 100644 --- a/src/.aspect/cli/config.yaml +++ b/src/.aspect/cli/config.yaml @@ -1,3 +1,4 @@ lint: aspects: - //tools/lint:linters.bzl%ruff + # - //tools/lint:linters.bzl%clang_tidy diff --git a/src/.clang-format b/src/.clang-format new file mode 100644 index 0000000..eac44b1 --- /dev/null +++ b/src/.clang-format @@ -0,0 +1,225 @@ +--- +Language: Cpp +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 105 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: NextLine +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 3 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +PPIndentWidth: -1 +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: pb + BasedOnStyle: google +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Auto +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/src/BUILD b/src/BUILD index cd8de03..da79029 100644 --- a/src/BUILD +++ b/src/BUILD @@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"]) exports_files( [ ".ruff.toml", + ".clang-format" ], visibility = ["//visibility:public"], ) diff --git a/src/MODULE.bazel b/src/MODULE.bazel index 16ff9f1..2fe83bc 100644 --- a/src/MODULE.bazel +++ b/src/MODULE.bazel @@ -18,6 +18,19 @@ module(name = "das") # Bazel to run linters and formatters bazel_dep(name = "aspect_rules_lint", version = "1.2.0") +bazel_dep(name = "toolchains_llvm", version = "1.3.0") +bazel_dep(name = "bazel_skylib", version = "1.7.1") + + + +llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") +llvm.toolchain( + llvm_versions = { + "": "16.0.0", + "darwin-x86_64": "15.0.7", + }, +) +use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm") # C++ diff --git a/src/MODULE.bazel.lock b/src/MODULE.bazel.lock index e3f3c94..5e86800 100644 --- a/src/MODULE.bazel.lock +++ b/src/MODULE.bazel.lock @@ -303,6 +303,8 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/source.json": "32bd87e5f4d7acc57c5b2ff7c325ae3061d5e242c0c4c214ae87e0f1c13e54cb", + "https://bcr.bazel.build/modules/toolchains_llvm/1.3.0/MODULE.bazel": "6e02731e51f7eb2ec4b01c5e79e722bf738a631f6e03d9b4917cbf2cb027bee1", + "https://bcr.bazel.build/modules/toolchains_llvm/1.3.0/source.json": "4ce0373a89c6df34dd37cd67285bb871d8e225d30dcb67dd093e077a04bbbb71", "https://bcr.bazel.build/modules/toolchains_protoc/0.2.1/MODULE.bazel": "2f08433ff5e659069b3a1abfee2377d68f510f2de1da50678ed992c455b4ff91", "https://bcr.bazel.build/modules/toolchains_protoc/0.2.1/source.json": "4ee6b007b62e1b9e493b00ccc60e61a258633f304b74813b6e7f7234927be94c", "https://bcr.bazel.build/modules/upb/0.0.0-20211020-160625a/MODULE.bazel": "6cced416be2dc5b9c05efd5b997049ba795e5e4e6fafbe1624f4587767638928", @@ -7016,6 +7018,87 @@ ] } }, + "@@toolchains_llvm+//toolchain/extensions:llvm.bzl%llvm": { + "general": { + "bzlTransitiveDigest": "2eLMaPh4QKrn3wPljYBu5jSkkp9DfCf4yGKTR9lBN3c=", + "usagesDigest": "IzLZJo6jscH0wDdOUqR2z5ZKOHfkhS4PKLUmCbhjU2I=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "llvm_toolchain_llvm": { + "repoRuleId": "@@toolchains_llvm+//toolchain:rules.bzl%llvm", + "attributes": { + "alternative_llvm_sources": [], + "auth_patterns": {}, + "distribution": "auto", + "exec_arch": "", + "exec_os": "", + "libclang_rt": {}, + "llvm_mirror": "", + "llvm_version": "", + "llvm_versions": { + "": "16.0.0", + "darwin-x86_64": "15.0.7" + }, + "netrc": "", + "sha256": {}, + "strip_prefix": {}, + "urls": {} + } + }, + "llvm_toolchain": { + "repoRuleId": "@@toolchains_llvm+//toolchain:rules.bzl%toolchain", + "attributes": { + "absolute_paths": false, + "archive_flags": {}, + "compile_flags": {}, + "conly_flags": {}, + "coverage_compile_flags": {}, + "coverage_link_flags": {}, + "cxx_builtin_include_directories": {}, + "cxx_flags": {}, + "cxx_standard": {}, + "dbg_compile_flags": {}, + "exec_arch": "", + "exec_os": "", + "extra_exec_compatible_with": {}, + "extra_target_compatible_with": {}, + "link_flags": {}, + "link_libs": {}, + "llvm_versions": { + "": "16.0.0", + "darwin-x86_64": "15.0.7" + }, + "opt_compile_flags": {}, + "opt_link_flags": {}, + "stdlib": {}, + "target_settings": {}, + "unfiltered_compile_flags": {}, + "toolchain_roots": {}, + "sysroot": {} + } + } + }, + "recordedRepoMappingEntries": [ + [ + "toolchains_llvm+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "toolchains_llvm+", + "bazel_tools", + "bazel_tools" + ], + [ + "toolchains_llvm+", + "toolchains_llvm", + "toolchains_llvm+" + ] + ] + } + }, "@@toolchains_protoc+//protoc:extensions.bzl%protoc": { "general": { "bzlTransitiveDigest": "HnmcD4ia7/1ZuQnymt4OGHXrW62MmIgwCtHByGQ7LQs=", diff --git a/src/attention_broker/AttentionBrokerServer.cc b/src/attention_broker/AttentionBrokerServer.cc index 9193c6b..9194679 100644 --- a/src/attention_broker/AttentionBrokerServer.cc +++ b/src/attention_broker/AttentionBrokerServer.cc @@ -1,25 +1,20 @@ -#include "RequestSelector.h" #include "AttentionBrokerServer.h" -using namespace attention_broker_server; +#include "RequestSelector.h" -const double AttentionBrokerServer::RENT_RATE; -const double AttentionBrokerServer::SPREADING_RATE_LOWERBOUND; -const double AttentionBrokerServer::SPREADING_RATE_UPPERBOUND; +using namespace attention_broker_server; // -------------------------------------------------------------------------------- // Public methods - -AttentionBrokerServer::AttentionBrokerServer() { - this->global_context = "global"; - this->stimulus_requests = new SharedQueue(); - this->correlation_requests = new SharedQueue(); - this->worker_threads = new WorkerThreads(stimulus_requests, correlation_requests); - HebbianNetwork *network = new HebbianNetwork(); - this->hebbian_network[this->global_context] = network; - this->updater = HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); - this->stimulus_spreader = StimulusSpreader::factory(StimulusSpreaderType::TOKEN); +AttentionBrokerServer::AttentionBrokerServer() + : stimulus_requests(new SharedQueue()), + correlation_requests(new SharedQueue()), + worker_threads(new WorkerThreads(stimulus_requests, correlation_requests)), + updater(HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT)), + stimulus_spreader(StimulusSpreader::factory(StimulusSpreaderType::TOKEN)) { + auto* network = new HebbianNetwork(); + this->hebbian_network[this->global_context] = network; } AttentionBrokerServer::~AttentionBrokerServer() { @@ -29,7 +24,7 @@ AttentionBrokerServer::~AttentionBrokerServer() { delete this->correlation_requests; delete this->updater; delete this->stimulus_spreader; - for (auto pair:this->hebbian_network) { + for (const auto& pair : this->hebbian_network) { delete pair.second; } } @@ -41,24 +36,28 @@ void AttentionBrokerServer::graceful_shutdown() { // RPC API -Status AttentionBrokerServer::ping(ServerContext* grpc_context, const dasproto::Empty *request, dasproto::Ack* reply) { +Status AttentionBrokerServer::ping(ServerContext* /*grpc_context*/, + const dasproto::Empty* /*request*/, + dasproto::Ack* reply) { reply->set_msg("PING"); if (rpc_api_enabled) { return Status::OK; - } else{ + } else { return Status::CANCELLED; } } -Status AttentionBrokerServer::stimulate(ServerContext* grpc_context, const dasproto::HandleCount *request, dasproto::Ack* reply) { +Status AttentionBrokerServer::stimulate(ServerContext* /*grpc_context*/, + const dasproto::HandleCount* request, + dasproto::Ack* reply) { #ifdef DEBUG cout << "AttentionBrokerServer::stimulate() BEGIN" << endl; cout << "Context: " << request->context() << endl; #endif if (request->map_size() > 0) { - HebbianNetwork *network = select_hebbian_network(request->context()); - ((dasproto::HandleCount *) request)->set_hebbian_network((long) network); - //this->stimulus_requests->enqueue((void *) request); + HebbianNetwork* network = select_hebbian_network(request->context()); + ((dasproto::HandleCount*) request)->set_hebbian_network((long) network); + // this->stimulus_requests->enqueue((void *) request); this->stimulus_spreader->spread_stimuli(request); } reply->set_msg("STIMULATE"); @@ -67,20 +66,22 @@ Status AttentionBrokerServer::stimulate(ServerContext* grpc_context, const daspr #endif if (rpc_api_enabled) { return Status::OK; - } else{ + } else { return Status::CANCELLED; } } -Status AttentionBrokerServer::correlate(ServerContext* grpc_context, const dasproto::HandleList *request, dasproto::Ack* reply) { +Status AttentionBrokerServer::correlate(ServerContext* /*grpc_context*/, + const dasproto::HandleList* request, + dasproto::Ack* reply) { #ifdef DEBUG cout << "AttentionBrokerServer::correlate() BEGIN" << endl; cout << "Context: " << request->context() << endl; #endif if (request->list_size() > 0) { - HebbianNetwork *network = select_hebbian_network(request->context()); - ((dasproto::HandleList *) request)->set_hebbian_network((long) network); - //this->correlation_requests->enqueue((void *) request); + HebbianNetwork* network = select_hebbian_network(request->context()); + ((dasproto::HandleList*) request)->set_hebbian_network((long) network); + // this->correlation_requests->enqueue((void *) request); this->updater->correlation(request); } reply->set_msg("CORRELATE"); @@ -94,17 +95,19 @@ Status AttentionBrokerServer::correlate(ServerContext* grpc_context, const daspr } } -Status AttentionBrokerServer::get_importance(ServerContext *grpc_context, const dasproto::HandleList *request, dasproto::ImportanceList *reply) { +Status AttentionBrokerServer::get_importance(ServerContext* /*grpc_context*/, + const dasproto::HandleList* request, + dasproto::ImportanceList* reply) { #ifdef DEBUG cout << "AttentionBrokerServer::get_importance() BEGIN" << endl; cout << "Context: " << request->context() << endl; #endif if (this->rpc_api_enabled) { - int num_handles = request->list_size(); + int const num_handles = request->list_size(); if (num_handles > 0) { - HebbianNetwork *network = select_hebbian_network(request->context()); + HebbianNetwork* network = select_hebbian_network(request->context()); for (int i = 0; i < num_handles; i++) { - float importance = network->get_node_importance(request->list(i)); + float const importance = network->get_node_importance(request->list(i)); reply->add_list(importance); } } @@ -121,12 +124,12 @@ Status AttentionBrokerServer::get_importance(ServerContext *grpc_context, const // Private methods // -HebbianNetwork *AttentionBrokerServer::select_hebbian_network(const string &context) { - HebbianNetwork *network; - if ((context != "") && (this->hebbian_network.find(context) != this->hebbian_network.end())) { +HebbianNetwork* AttentionBrokerServer::select_hebbian_network(const string& context) { + HebbianNetwork* network = nullptr; + if ((!context.empty()) && (this->hebbian_network.find(context) != this->hebbian_network.end())) { network = this->hebbian_network[context]; } - if (context == "") { + if (context.empty()) { network = this->hebbian_network[this->global_context]; } else { if (this->hebbian_network.find(context) == this->hebbian_network.end()) { diff --git a/src/attention_broker/AttentionBrokerServer.h b/src/attention_broker/AttentionBrokerServer.h index 8269559..95e578b 100644 --- a/src/attention_broker/AttentionBrokerServer.h +++ b/src/attention_broker/AttentionBrokerServer.h @@ -5,18 +5,19 @@ #include #include -#include "attention_broker.grpc.pb.h" -#include "SharedQueue.h" -#include "WorkerThreads.h" + #include "HebbianNetwork.h" #include "HebbianNetworkUpdater.h" +#include "SharedQueue.h" #include "StimulusSpreader.h" +#include "WorkerThreads.h" +#include "attention_broker.grpc.pb.h" +using dasproto::AttentionBroker; using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::Status; -using dasproto::AttentionBroker; namespace attention_broker_server { @@ -29,122 +30,137 @@ namespace attention_broker_server { * Some parameters related to the stimulus spreading algorithms are also * stored in this class as static fields. Detailed description of them are * provided in StimulsSpreader. They are defined here because we may want - * to allow them to be modified by some homeostasis process running independently - * from StimulusSpreading. + * to allow them to be modified by some homeostasis process running + * independently from StimulusSpreading. */ -class AttentionBrokerServer final: public AttentionBroker::Service { - - public: - - /** - * Basic no-parameters constructor. - * Creates and initializes two request queues. One for stimuli spreading and - * another one for atom correlation. Worker threads to process such queues are - * also created inside a WorkerThread object. - * - * Different contexts are represented using different HebianNetwork objects. New - * contexts are created by caller's request but a default GLOBAL context is created - * here to be used whenever the caller don't specify a context. - */ - AttentionBrokerServer(); - - /** - * Destructor. - * - * Gracefully shutdown the GRPC server by stopping accepting new requests (any new request - * received after starting a shutdown process is denied and an error is returned to the - * caller) and waiting for all requests currently in the queues to be processed. Once all - * queues are empty, all worker threads are stopped and the queues and all other state structures - * are destroyed. - */ - ~AttentionBrokerServer(); - - static const unsigned int WORKER_THREADS_COUNT = 10; /// Number of working threads. - - - // Stimuli spreading parameters - string global_context; - constexpr const static double RENT_RATE = 0.50; /// double in [0..1] range. - constexpr const static double SPREADING_RATE_LOWERBOUND = 0.01; /// double in [0..1] range. - constexpr const static double SPREADING_RATE_UPPERBOUND = 0.10; /// double in [0..1] range. - - // RPC API - - /** - * Used by caller to check if AttentionBroker is running. - * - * @param grpc_context GRPC context object. - * @param request Empty request. - * @param reply The message which will be send back to the caller with a simple ACK. - * - * @return GRPC status OK if request were properly processed or CANCELLED otherwise. - */ - Status ping(ServerContext *grpc_context, const dasproto::Empty *request, dasproto::Ack *reply) override; - - /** - * Spread stimuli according to the passed request. - * - * Boost importance of passed atoms and run one cycle of stimuli spreading. The algorithm is explained - * in StimulusSpreader. - * - * @param grpc_context GRPC context object. - * @param request The request contains a list of handles of the atoms which should have the boost in - * importance as well as an associated integer indicating the proportion in which the boost should - * happen related to the other atoms in the same request. - * @param reply The message which will be send back to the caller with a simple ACK. - * - * @return GRPC status OK if request were properly processed or CANCELLED otherwise. - */ - Status stimulate(ServerContext *grpc_context, const dasproto::HandleCount *request, dasproto::Ack *reply) override; - - /** - * Correlates atoms passed in the request. - * - * @param grpc_context GRPC context object. - * @param request The request contains a list of handles of the atoms which should be correlated. - * @param reply The message which will be send back to the caller with a simple ACK. - * - * @return GRPC status OK if request were properly processed or CANCELLED otherwise. - */ - Status correlate(ServerContext* grpc_context, const dasproto::HandleList* request, dasproto::Ack* reply) override; - - /** - * Return importance of atoms passed in the request. - * - * - * @param grpc_context GRPC context object. - * @param request The request contains a list of handles of the atoms whose importrance are to be returned. - * @param reply A list with importance of atoms IN THE SAME ORDER they appear in the request. - * - * @return GRPC status OK if request were properly processed or CANCELLED otherwise. - */ - Status get_importance(ServerContext *grpc_context, const dasproto::HandleList *request, dasproto::ImportanceList *reply) override; - - // Other public methods - - /** - * Gracefully stop this GRPC server. - * - * Gracefully shutdown the GRPC server by stopping accepting new requests (any new request - * received after starting a shutdown process is denied and an error is returned to the - * caller) and waiting for all requests currently in the queues to be processed. - */ - void graceful_shutdown(); /// Gracefully stop this GRPC server. - - private: - - bool rpc_api_enabled = true; - SharedQueue *stimulus_requests; - SharedQueue *correlation_requests; - WorkerThreads *worker_threads; - unordered_map hebbian_network; - HebbianNetworkUpdater *updater; - StimulusSpreader *stimulus_spreader; - - - HebbianNetwork *select_hebbian_network(const string &context); +class AttentionBrokerServer final : public AttentionBroker::Service { + public: + /** + * Basic no-parameters constructor. + * Creates and initializes two request queues. One for stimuli spreading and + * another one for atom correlation. Worker threads to process such queues are + * also created inside a WorkerThread object. + * + * Different contexts are represented using different HebianNetwork objects. + * New contexts are created by caller's request but a default GLOBAL context + * is created here to be used whenever the caller don't specify a context. + */ + AttentionBrokerServer(); + + /** + * Destructor. + * + * Gracefully shutdown the GRPC server by stopping accepting new requests (any + * new request received after starting a shutdown process is denied and an + * error is returned to the caller) and waiting for all requests currently in + * the queues to be processed. Once all queues are empty, all worker threads + * are stopped and the queues and all other state structures are destroyed. + */ + ~AttentionBrokerServer(); + + static const unsigned int WORKER_THREADS_COUNT = 10; /// Number of working threads. + + // Stimuli spreading parameters + string global_context; + constexpr const static double RENT_RATE = 0.50; /// double in [0..1] range. + constexpr const static double SPREADING_RATE_LOWERBOUND = 0.01; /// double in [0..1] range. + constexpr const static double SPREADING_RATE_UPPERBOUND = 0.10; /// double in [0..1] range. + + // RPC API + + /** + * Used by caller to check if AttentionBroker is running. + * + * @param grpc_context GRPC context object. + * @param request Empty request. + * @param reply The message which will be send back to the caller with a + * simple ACK. + * + * @return GRPC status OK if request were properly processed or CANCELLED + * otherwise. + */ + Status ping(ServerContext* grpc_context, + const dasproto::Empty* request, + dasproto::Ack* reply) override; + + /** + * Spread stimuli according to the passed request. + * + * Boost importance of passed atoms and run one cycle of stimuli spreading. + * The algorithm is explained in StimulusSpreader. + * + * @param grpc_context GRPC context object. + * @param request The request contains a list of handles of the atoms which + * should have the boost in importance as well as an associated integer + * indicating the proportion in which the boost should happen related to the + * other atoms in the same request. + * @param reply The message which will be send back to the caller with a + * simple ACK. + * + * @return GRPC status OK if request were properly processed or CANCELLED + * otherwise. + */ + Status stimulate(ServerContext* grpc_context, + const dasproto::HandleCount* request, + dasproto::Ack* reply) override; + + /** + * Correlates atoms passed in the request. + * + * @param grpc_context GRPC context object. + * @param request The request contains a list of handles of the atoms which + * should be correlated. + * @param reply The message which will be send back to the caller with a + * simple ACK. + * + * @return GRPC status OK if request were properly processed or CANCELLED + * otherwise. + */ + Status correlate(ServerContext* grpc_context, + const dasproto::HandleList* request, + dasproto::Ack* reply) override; + + /** + * Return importance of atoms passed in the request. + * + * + * @param grpc_context GRPC context object. + * @param request The request contains a list of handles of the atoms whose + * importrance are to be returned. + * @param reply A list with importance of atoms IN THE SAME ORDER they appear + * in the request. + * + * @return GRPC status OK if request were properly processed or CANCELLED + * otherwise. + */ + Status get_importance(ServerContext* grpc_context, + const dasproto::HandleList* request, + dasproto::ImportanceList* reply) override; + + // Other public methods + + /** + * Gracefully stop this GRPC server. + * + * Gracefully shutdown the GRPC server by stopping accepting new requests (any + * new request received after starting a shutdown process is denied and an + * error is returned to the caller) and waiting for all requests currently in + * the queues to be processed. + */ + void graceful_shutdown(); /// Gracefully stop this GRPC server. + + private: + bool rpc_api_enabled = true; + SharedQueue* stimulus_requests; + SharedQueue* correlation_requests; + WorkerThreads* worker_threads; + unordered_map hebbian_network; + HebbianNetworkUpdater* updater; + StimulusSpreader* stimulus_spreader; + + HebbianNetwork* select_hebbian_network(const string& context); }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_ATTENTIONBROKERSERVER_H +#endif // _ATTENTION_BROKER_SERVER_ATTENTIONBROKERSERVER_H diff --git a/src/attention_broker/HandleTrie.cc b/src/attention_broker/HandleTrie.cc index b0ca670..4121171 100644 --- a/src/attention_broker/HandleTrie.cc +++ b/src/attention_broker/HandleTrie.cc @@ -1,24 +1,23 @@ -#include "Utils.h" -#include "expression_hasher.h" #include "HandleTrie.h" + #include #include +#include "Utils.h" +#include "expression_hasher.h" + using namespace attention_broker_server; using namespace commons; -HandleTrie::TrieValue::TrieValue() { -} +HandleTrie::TrieValue::TrieValue() = default; -HandleTrie::TrieValue::~TrieValue() { -} +HandleTrie::TrieValue::~TrieValue() = default; -HandleTrie::TrieNode::TrieNode() { - children = new TrieNode*[TRIE_ALPHABET_SIZE]; +HandleTrie::TrieNode::TrieNode() : children(new TrieNode*[TRIE_ALPHABET_SIZE]) { for (unsigned int i = 0; i < TRIE_ALPHABET_SIZE; i++) { - children[i] = NULL; + children[i] = nullptr; } - this->value = NULL; + this->value = nullptr; this->suffix_start = 0; } @@ -26,13 +25,11 @@ HandleTrie::TrieNode::~TrieNode() { for (unsigned int i = 0; i < TRIE_ALPHABET_SIZE; i++) { delete children[i]; } - delete [] children; + delete[] children; delete value; } -string HandleTrie::TrieValue::to_string() { - return ""; -} +string HandleTrie::TrieValue::to_string() { return ""; } bool HandleTrie::TLB_INITIALIZED = false; unsigned char HandleTrie::TLB[256]; @@ -40,23 +37,22 @@ unsigned char HandleTrie::TLB[256]; // -------------------------------------------------------------------------------- // Public methods - -string HandleTrie::TrieNode::to_string() { +string HandleTrie::TrieNode::to_string() const { string answer; if (suffix_start == 0) { answer = "''"; } else { - int n = suffix.size() - suffix_start; + int const n = suffix.size() - suffix_start; answer = suffix.substr(0, suffix_start) + "." + suffix.substr(suffix_start, n); } answer += " ["; for (unsigned int i = 0; i < TRIE_ALPHABET_SIZE; i++) { - if (children[i] != NULL) { + if (children[i] != nullptr) { answer += ("*"); } } answer += "] "; - if (value != NULL) { + if (value != nullptr) { answer += value->to_string(); } return answer; @@ -67,33 +63,30 @@ HandleTrie::HandleTrie(unsigned int key_size) { Utils::error("Invalid key size: " + to_string(key_size)); } this->key_size = key_size; - if (! HandleTrie::TLB_INITIALIZED) { + if (!HandleTrie::TLB_INITIALIZED) { HandleTrie::TLB_INIT(); } root = new TrieNode(); } -HandleTrie::~HandleTrie() { - delete root; -} - -HandleTrie::TrieValue *HandleTrie::insert(const string &key, TrieValue *value) { +HandleTrie::~HandleTrie() { delete root; } +HandleTrie::TrieValue* HandleTrie::insert(const string& key, TrieValue* value) const { if (key.size() != key_size) { Utils::error("Invalid key size: " + to_string(key.size()) + " != " + to_string(key_size)); } - TrieNode *tree_cursor = root; - TrieNode *parent = root; - TrieNode *child; - TrieNode *split; + TrieNode* tree_cursor = root; + TrieNode* parent = root; + TrieNode* child = nullptr; + TrieNode* split = nullptr; unsigned char key_cursor = 0; tree_cursor->trie_node_mutex.lock(); while (true) { - unsigned char c = TLB[(unsigned char) key[key_cursor]]; - if (tree_cursor->children[c] == NULL) { + unsigned char const c = TLB[(unsigned char) key[key_cursor]]; + if (tree_cursor->children[c] == nullptr) { if (tree_cursor->suffix_start > 0) { - unsigned char c_key_pred = TLB[(unsigned char) key[key_cursor -1]]; + unsigned char const c_key_pred = TLB[(unsigned char) key[key_cursor - 1]]; if (key[key_cursor] == tree_cursor->suffix[key_cursor]) { child = new TrieNode(); child->trie_node_mutex.lock(); @@ -108,7 +101,8 @@ HandleTrie::TrieValue *HandleTrie::insert(const string &key, TrieValue *value) { child->suffix = key; child->suffix_start = key_cursor + 1; child->value = value; - unsigned char c_tree_cursor = TLB[(unsigned char) tree_cursor->suffix[tree_cursor->suffix_start]]; + unsigned char const c_tree_cursor = + TLB[(unsigned char) tree_cursor->suffix[tree_cursor->suffix_start]]; tree_cursor->suffix_start++; split = new TrieNode(); split->children[c] = child; @@ -141,7 +135,7 @@ HandleTrie::TrieValue *HandleTrie::insert(const string &key, TrieValue *value) { tree_cursor->trie_node_mutex.lock(); if (tree_cursor->suffix_start > 0) { bool match = true; - unsigned int n = key.size(); + unsigned int const n = key.size(); for (unsigned int i = key_cursor; i < n; i++) { if (key[i] != tree_cursor->suffix[i]) { match = false; @@ -163,20 +157,19 @@ HandleTrie::TrieValue *HandleTrie::insert(const string &key, TrieValue *value) { } } -HandleTrie::TrieValue *HandleTrie::lookup(const string &key) { - +HandleTrie::TrieValue* HandleTrie::lookup(const string& key) const { if (key.size() != key_size) { Utils::error("Invalid key size: " + to_string(key.size()) + " != " + to_string(key_size)); } - TrieNode *tree_cursor = root; - TrieValue *value; + TrieNode* tree_cursor = root; + TrieValue* value = nullptr; unsigned char key_cursor = 0; tree_cursor->trie_node_mutex.lock(); - while (tree_cursor != NULL) { + while (tree_cursor != nullptr) { if (tree_cursor->suffix_start > 0) { bool match = true; - unsigned int n = key.size(); + unsigned int const n = key.size(); for (unsigned int i = key_cursor; i < n; i++) { if (key[i] != tree_cursor->suffix[i]) { match = false; @@ -186,31 +179,32 @@ HandleTrie::TrieValue *HandleTrie::lookup(const string &key) { if (match) { value = tree_cursor->value; } else { - value = NULL; + value = nullptr; } tree_cursor->trie_node_mutex.unlock(); return value; } else { - unsigned char c = TLB[(unsigned char) key[key_cursor]]; - TrieNode *child = tree_cursor->children[c]; + unsigned char const c = TLB[(unsigned char) key[key_cursor]]; + TrieNode* child = tree_cursor->children[c]; tree_cursor->trie_node_mutex.unlock(); tree_cursor = child; key_cursor++; - if (tree_cursor != NULL) { + if (tree_cursor != nullptr) { tree_cursor->trie_node_mutex.lock(); } } } - return NULL; + return nullptr; } -void HandleTrie::traverse(bool keep_root_locked, bool (*visit_function)(TrieNode *node, void *data), void *data) { - - stack node_stack; - TrieNode *cursor; +void HandleTrie::traverse(bool keep_root_locked, + bool (*visit_function)(TrieNode* node, void* data), + void* data) const { + stack node_stack; + TrieNode* cursor = nullptr; node_stack.push(root); - while (! node_stack.empty()) { + while (!node_stack.empty()) { cursor = node_stack.top(); node_stack.pop(); cursor->trie_node_mutex.lock(); @@ -223,8 +217,8 @@ void HandleTrie::traverse(bool keep_root_locked, bool (*visit_function)(TrieNode return; } } else { - for (unsigned int i = TRIE_ALPHABET_SIZE - 1; ; i--) { - if (cursor->children[i] != NULL) { + for (unsigned int i = TRIE_ALPHABET_SIZE - 1;; i--) { + if (cursor->children[i] != nullptr) { node_stack.push(cursor->children[i]); } if (i == 0) { @@ -232,7 +226,7 @@ void HandleTrie::traverse(bool keep_root_locked, bool (*visit_function)(TrieNode } } } - if ((! keep_root_locked) || (cursor != root)) { + if ((!keep_root_locked) || (cursor != root)) { cursor->trie_node_mutex.unlock(); } } diff --git a/src/attention_broker/HandleTrie.h b/src/attention_broker/HandleTrie.h index 34e2c97..861c1bc 100644 --- a/src/attention_broker/HandleTrie.h +++ b/src/attention_broker/HandleTrie.h @@ -13,82 +13,85 @@ namespace attention_broker_server { /** * Data abstraction implementing a map handle->value using a trie (prefix tree). * - * This data structure is basicaly like a hashmap mapping from handles to objects of - * type HandleTrie::TrieValue. + * This data structure is basicaly like a hashmap mapping from handles to + * objects of type HandleTrie::TrieValue. * - * When a (key, value) pair is inserted and key is already present, the method merge() - * in value is called passing the newly inserted value. + * When a (key, value) pair is inserted and key is already present, the method + * merge() in value is called passing the newly inserted value. */ class HandleTrie { - -public: - + public: /** * Virtual basic class to be extended by objects used as "values". */ class TrieValue { - protected: - TrieValue(); /// basic empty constructor. - public: - virtual ~TrieValue(); /// Destructor. - virtual void merge(TrieValue *other) = 0; /// Called when a repeated handle is inserted. - virtual string to_string(); /// Returns a string representation of the value object. - + protected: + TrieValue(); /// basic empty constructor. + public: + virtual ~TrieValue(); /// Destructor. + virtual void merge(TrieValue* other) = 0; /// Called when a repeated handle is inserted. + virtual string to_string(); /// Returns a string representation of the value object. }; /** * A node in the prefix tree used to store keys. */ class TrieNode { - public: - TrieNode(); /// Basic empty constructor. - ~TrieNode(); /// Destructor. - - TrieNode **children; /// Array with children of this node. - TrieValue *value; /// Value attached to this node or NULL if none. - string suffix; /// The key (handle) attached to this node (leafs) or NULL if none (internal nodes). - unsigned char suffix_start; /// The point in the suffix from which this node (leaf) differs from its siblings. - mutex trie_node_mutex; - - string to_string(); /// Returns a string representation of this node. + public: + TrieNode(); /// Basic empty constructor. + ~TrieNode(); /// Destructor. + + TrieNode** children; /// Array with children of this node. + TrieValue* value; /// Value attached to this node or NULL if none. + string suffix; /// The key (handle) attached to this node (leafs) or NULL if + /// none (internal nodes). + unsigned char suffix_start; /// The point in the suffix from which this node + /// (leaf) differs from its siblings. + mutex trie_node_mutex; + + string to_string(); /// Returns a string representation of this node. }; - HandleTrie(unsigned int key_size); /// Basic constructor. - ~HandleTrie(); /// Destructor. + HandleTrie(unsigned int key_size); /// Basic constructor. + ~HandleTrie(); /// Destructor. /** - * Insert a new key in this HandleTrie or merge its value if the key is already present. + * Insert a new key in this HandleTrie or merge its value if the key is + * already present. * * @param key Handle being inserted. * @param value HandleTrie::TrieValue object being inserted. * - * @return The resulting HandleTrie::TrieValue object after insertion (and eventually the merge) is processed. + * @return The resulting HandleTrie::TrieValue object after insertion (and + * eventually the merge) is processed. */ - TrieValue *insert(const string &key, TrieValue *value); + TrieValue* insert(const string& key, TrieValue* value); /** * Lookup for a given handle. * * @param key Handle being searched. * - * @return The HandleTrie::TrieValue object attached to the passed key or NULL if none. + * @return The HandleTrie::TrieValue object attached to the passed key or NULL + * if none. */ - TrieValue *lookup(const string &key); + TrieValue* lookup(const string& key); /** - * Traverse all keys (in-order) calling the passed visit_function once per stored value. + * Traverse all keys (in-order) calling the passed visit_function once per + * stored value. * - * @param keep_root_locked Keep root HandleTrie::TrieNode locked during the whole traversing - * releasing the lock when it ends. + * @param keep_root_locked Keep root HandleTrie::TrieNode locked during the + * whole traversing releasing the lock when it ends. * @param visit_function Function to be called when each value is visited. - * @param data Additional information passed to visit_function or NULL if none. + * @param data Additional information passed to visit_function or NULL if + * none. */ - void traverse(bool keep_root_locked, bool (*visit_function)(TrieNode *node, void *data), void *data); - - TrieNode *root; + void traverse(bool keep_root_locked, bool (*visit_function)(TrieNode* node, void* data), void* data); -private: + TrieNode* root; + private: static unsigned char TLB[256]; static bool TLB_INITIALIZED; static void TLB_INIT() { @@ -114,6 +117,6 @@ class HandleTrie { unsigned int key_size; }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_HANDLETRIE_H +#endif // _ATTENTION_BROKER_SERVER_HANDLETRIE_H diff --git a/src/attention_broker/HebbianNetwork.cc b/src/attention_broker/HebbianNetwork.cc index 62042f1..cacd3ca 100644 --- a/src/attention_broker/HebbianNetwork.cc +++ b/src/attention_broker/HebbianNetwork.cc @@ -1,6 +1,10 @@ +#include "HebbianNetwork.h" + +#include + #include #include -#include "HebbianNetwork.h" + #include "Utils.h" #include "expression_hasher.h" @@ -9,35 +13,33 @@ using namespace attention_broker_server; // -------------------------------------------------------------------------------- // Public methods -HebbianNetwork::HebbianNetwork() { - nodes = new HandleTrie(HANDLE_HASH_SIZE - 1); - largest_arity = 0; +HebbianNetwork::HebbianNetwork() : nodes(new HandleTrie(HANDLE_HASH_SIZE - 1)) { tokens_mutex.lock(); - tokens_to_distribute = 1.0; + tokens_mutex.unlock(); } -HebbianNetwork::~HebbianNetwork() { - delete nodes; -} +HebbianNetwork::~HebbianNetwork() { delete nodes; } string HebbianNetwork::Node::to_string() { - return "(" + std::to_string(count) + ", " + std::to_string(importance) + ", " + std::to_string(arity) + ")"; + return "(" + std::to_string(count) + ", " + std::to_string(importance) + ", " + + std::to_string(arity) + ")"; } -string HebbianNetwork::Edge::to_string() { - return "(" + std::to_string(count) + ")"; -} +string HebbianNetwork::Edge::to_string() { return "(" + std::to_string(count) + ")"; } -HebbianNetwork::Node *HebbianNetwork::add_node(string handle) { - return (Node *) nodes->insert(handle, new HebbianNetwork::Node()); +HebbianNetwork::Node* HebbianNetwork::add_node(const string& handle) { + return dynamic_cast(nodes->insert(handle, new HebbianNetwork::Node())); } -HebbianNetwork::Edge *HebbianNetwork::add_asymmetric_edge(string handle1, string handle2, Node *node1, Node *node2) { - if (node1 == NULL) { - node1 = (Node *) nodes->lookup(handle1); +HebbianNetwork::Edge* HebbianNetwork::add_asymmetric_edge(const string& handle1, + const string& handle2, + Node* node1, + Node* node2) { + if (node1 == nullptr) { + node1 = dynamic_cast(nodes->lookup(handle1)); } - Edge *edge = (Edge *) node1->neighbors->insert(handle2, new HebbianNetwork::Edge()); + Edge* edge = dynamic_cast(node1->neighbors->insert(handle2, new HebbianNetwork::Edge())); if (edge->count == 1) { // First time this edge is added edge->node1 = node1; @@ -52,38 +54,41 @@ HebbianNetwork::Edge *HebbianNetwork::add_asymmetric_edge(string handle1, string return edge; } -void HebbianNetwork::add_symmetric_edge(string handle1, string handle2, Node *node1, Node *node2) { +void HebbianNetwork::add_symmetric_edge(const string& handle1, + const string& handle2, + Node* node1, + Node* node2) { add_asymmetric_edge(handle1, handle2, node1, node2); add_asymmetric_edge(handle2, handle1, node2, node1); } -HebbianNetwork::Node *HebbianNetwork::lookup_node(string handle) { - return (Node *) nodes->lookup(handle); +HebbianNetwork::Node* HebbianNetwork::lookup_node(const string& handle) { + return dynamic_cast(nodes->lookup(handle)); } -unsigned int HebbianNetwork::get_node_count(string handle) { - Node *node = (Node *) nodes->lookup(handle); - if (node == NULL) { +unsigned int HebbianNetwork::get_node_count(const string& handle) { + Node* node = dynamic_cast(nodes->lookup(handle)); + if (node == nullptr) { return 0; } else { return node->count; } } -ImportanceType HebbianNetwork::get_node_importance(string handle) { - Node *node = (Node *) nodes->lookup(handle); - if (node == NULL) { +ImportanceType HebbianNetwork::get_node_importance(const string& handle) { + Node* node = dynamic_cast(nodes->lookup(handle)); + if (node == nullptr) { return 0; } else { return node->importance; } } -unsigned int HebbianNetwork::get_asymmetric_edge_count(string handle1, string handle2) { - Node *source = (Node *) nodes->lookup(handle1); - if (source != NULL) { - Edge *edge = (Edge *) source->neighbors->lookup(handle2); - if (edge != NULL) { +unsigned int HebbianNetwork::get_asymmetric_edge_count(const string& handle1, const string& handle2) { + Node* source = dynamic_cast(nodes->lookup(handle1)); + if (source != nullptr) { + Edge* edge = dynamic_cast(source->neighbors->lookup(handle2)); + if (edge != nullptr) { return edge->count; } } @@ -91,7 +96,7 @@ unsigned int HebbianNetwork::get_asymmetric_edge_count(string handle1, string ha } ImportanceType HebbianNetwork::alienate_tokens() { - ImportanceType answer; + ImportanceType answer = NAN; tokens_mutex.lock(); answer = tokens_to_distribute; tokens_to_distribute = 0.0; @@ -99,20 +104,16 @@ ImportanceType HebbianNetwork::alienate_tokens() { return answer; } -void HebbianNetwork::visit_nodes( - bool keep_root_locked, - bool (*visit_function)(HandleTrie::TrieNode *node, void *data), - void *data) { - +void HebbianNetwork::visit_nodes(bool keep_root_locked, + bool (*visit_function)(HandleTrie::TrieNode* node, void* data), + void* data) { nodes->traverse(keep_root_locked, visit_function, data); } -static inline void release_locks( - HandleTrie::TrieNode *root, - HandleTrie::TrieNode *cursor, - bool keep_root_locked, - bool release_root_after_end) { - +static inline void release_locks(HandleTrie::TrieNode* root, + HandleTrie::TrieNode* cursor, + bool keep_root_locked, + bool release_root_after_end) { if (keep_root_locked && release_root_after_end && (root != cursor)) { root->trie_node_mutex.unlock(); } diff --git a/src/attention_broker/HebbianNetwork.h b/src/attention_broker/HebbianNetwork.h index 37f8149..468ff4e 100644 --- a/src/attention_broker/HebbianNetwork.h +++ b/src/attention_broker/HebbianNetwork.h @@ -1,9 +1,10 @@ #ifndef _ATTENTION_BROKER_SERVER_HEBBIANNETWORK_H #define _ATTENTION_BROKER_SERVER_HEBBIANNETWORK_H -#include -#include #include +#include +#include + #include "HandleTrie.h" #include "expression_hasher.h" @@ -14,52 +15,53 @@ namespace attention_broker_server { typedef double ImportanceType; /** - * Data abstraction of an asymmetric Hebbian Network with only direct hebbian links. + * Data abstraction of an asymmetric Hebbian Network with only direct hebbian + * links. * - * A Hebbian Network, in the context of AttentionBrokerServer, is a directed graph with - * weights in the edges A->B representing the probability of B being present in a DAS - * query answer given that A is present. In other words, provided that the atom A is one of - * the atoms returned in a given query in DAS, the weight of the edge A->B in - * a HebbianNetwork is an estimate of the probability of B being present in the same answer. + * A Hebbian Network, in the context of AttentionBrokerServer, is a directed + * graph with weights in the edges A->B representing the probability of B being + * present in a DAS query answer given that A is present. In other words, + * provided that the atom A is one of the atoms returned in a given query in + * DAS, the weight of the edge A->B in a HebbianNetwork is an estimate of the + * probability of B being present in the same answer. * - * HebbianNetwork is asymmetric, meaning that the weight of A->B can be different from the - * weight of B->A. + * HebbianNetwork is asymmetric, meaning that the weight of A->B can be + * different from the weight of B->A. * - * All edges in HebbianNetwork are "direct" hebbian links meaning that they estimate the - * probability of B BEING present in a answer given that A is. There are no "reverse" - * hebbian links which would mean the probability of B being NOT present in an answer - * given that A is. + * All edges in HebbianNetwork are "direct" hebbian links meaning that they + * estimate the probability of B BEING present in a answer given that A is. + * There are no "reverse" hebbian links which would mean the probability of B + * being NOT present in an answer given that A is. * - * HebbianNetwork keeps nodes in a HandleTrie which is basically a data structure to map - * from handle to a value object (mostly like a hashmap but slightly more efficient because - * it makes the assumption that the key is a handle). So in the stored value object it stores - * another HandleTrie to keep track of the neighbors. So we have two types of value objects, - * one to represent Nodes and another one to represent Edges. + * HebbianNetwork keeps nodes in a HandleTrie which is basically a data + * structure to map from handle to a value object (mostly like a hashmap but + * slightly more efficient because it makes the assumption that the key is a + * handle). So in the stored value object it stores another HandleTrie to keep + * track of the neighbors. So we have two types of value objects, one to + * represent Nodes and another one to represent Edges. */ class HebbianNetwork { + public: + HebbianNetwork(); /// Basic constructor. + ~HebbianNetwork(); /// Destructor. -public: - - HebbianNetwork(); /// Basic constructor. - ~HebbianNetwork(); /// Destructor. - - unsigned int largest_arity; /// Largest arity among nodes in this network. + unsigned int largest_arity; /// Largest arity among nodes in this network. mutex largest_arity_mutex; - // Node and Link don't inherit from a common "Atom" class to avoid having virtual methods, - // which couldn't be properly inlined. + // Node and Link don't inherit from a common "Atom" class to avoid having + // virtual methods, which couldn't be properly inlined. /** * Node object used as the value in HandleTrie. */ - class Node: public HandleTrie::TrieValue { - public: - unsigned int arity; /// Number of neighbors of this Node. - unsigned int count; /// Count for this Node. - ImportanceType importance; /// Importance of this Node. - ImportanceType stimuli_to_spread; /// Amount of importance this node will spread in the next - /// stimuli spreading cycle. - HandleTrie *neighbors; // Neighbors of this Node. + class Node : public HandleTrie::TrieValue { + public: + unsigned int arity; /// Number of neighbors of this Node. + unsigned int count; /// Count for this Node. + ImportanceType importance; /// Importance of this Node. + ImportanceType stimuli_to_spread; /// Amount of importance this node will spread in the + /// next stimuli spreading cycle. + HandleTrie* neighbors; // Neighbors of this Node. Node() { arity = 0; count = 1; @@ -67,58 +69,58 @@ class HebbianNetwork { stimuli_to_spread = 0.0; neighbors = new HandleTrie(HANDLE_HASH_SIZE - 1); } - inline void merge(HandleTrie::TrieValue *other) { - count += ((Node *) other)->count; - importance += ((Node *) other)->importance; + inline void merge(HandleTrie::TrieValue* other) { + count += ((Node*) other)->count; + importance += ((Node*) other)->importance; } - string to_string(); /// String representation of this Node. + string to_string(); /// String representation of this Node. }; /** * Edge object used as the value in HandleTrie. */ - class Edge: public HandleTrie::TrieValue { - public: - unsigned int count; /// Count for this edge. - Node *node1; /// Source Node. - Node *node2; /// Target node. + class Edge : public HandleTrie::TrieValue { + public: + unsigned int count; /// Count for this edge. + Node* node1; /// Source Node. + Node* node2; /// Target node. Edge() { count = 1; node1 = node2 = NULL; } - inline void merge(HandleTrie::TrieValue *other) { - count += ((Edge *) other)->count; - } - string to_string(); /// String representation of this Edge. + inline void merge(HandleTrie::TrieValue* other) { count += ((Edge*) other)->count; } + string to_string(); /// String representation of this Edge. }; /** - * Adds a new node to this network or increase +1 to its count if it already exists. + * Adds a new node to this network or increase +1 to its count if it already + * exists. * * @param handle Atom being added. * * @return the value object attached to the node being inserted. */ - Node *add_node(string handle); + Node* add_node(string handle); /** - * Adds a new edge handle1->handle2 to this network or increase +1 to its count if it already exists. + * Adds a new edge handle1->handle2 to this network or increase +1 to its + * count if it already exists. * * @param handle1 Source of the edge. * @param handle2 Target of the edge. * * @return the value object attached to the edge being inserted. */ - Edge *add_asymmetric_edge(string handle1, string handle2, Node *node1, Node *node2); + Edge* add_asymmetric_edge(string handle1, string handle2, Node* node1, Node* node2); /** - * Adds new edges handle1->handle2 and handle2->handle1 to this network or increase +1 - * to their count if they already exist. + * Adds new edges handle1->handle2 and handle2->handle1 to this network or + * increase +1 to their count if they already exist. * * @param handle1 One of the nodes in the edge. * @param handle2 The other node in the edge. */ - void add_symmetric_edge(string handle1, string handle2, Node *node1, Node *node2); + void add_symmetric_edge(string handle1, string handle2, Node* node1, Node* node2); /** * Lookup and return the value attached to the passed handle. @@ -127,7 +129,7 @@ class HebbianNetwork { * * @return The value object attached to the node. */ - Node *lookup_node(string handle); + Node* lookup_node(string handle); /** * Lookup for the passed node and return its count. @@ -161,28 +163,27 @@ class HebbianNetwork { * Traverse the node's HandleTrie and call the passed function once for each * of the visited nodes. * - * @param keep_root_locked True iff HandleTrie root should be kept locked during - * all the traversal. If false, the root lock is freed just like any other internal - * trie node. - * @param visit_function Function to be called passing each visited node. This function + * @param keep_root_locked True iff HandleTrie root should be kept locked + * during all the traversal. If false, the root lock is freed just like any + * other internal trie node. + * @param visit_function Function to be called passing each visited node. This + * function * @param data Additional data to be passed to the visit_function. * * expects the Node and a pointer to eventual data used inside visit_function. */ - void visit_nodes( - bool keep_root_locked, - bool (*visit_function)(HandleTrie::TrieNode *node, void *data), - void *data); + void visit_nodes(bool keep_root_locked, + bool (*visit_function)(HandleTrie::TrieNode* node, void* data), + void* data); ImportanceType alienate_tokens(); -private: - - HandleTrie *nodes; + private: + HandleTrie* nodes; ImportanceType tokens_to_distribute; mutex tokens_mutex; }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_HEBBIANNETWORK_H +#endif // _ATTENTION_BROKER_SERVER_HEBBIANNETWORK_H diff --git a/src/attention_broker/HebbianNetworkUpdater.cc b/src/attention_broker/HebbianNetworkUpdater.cc index c9a954a..51699cf 100644 --- a/src/attention_broker/HebbianNetworkUpdater.cc +++ b/src/attention_broker/HebbianNetworkUpdater.cc @@ -1,50 +1,47 @@ -#include #include "HebbianNetworkUpdater.h" + +#include + #include "HebbianNetwork.h" #include "Utils.h" using namespace attention_broker_server; using namespace commons; -HebbianNetworkUpdater::HebbianNetworkUpdater() { -} +HebbianNetworkUpdater::HebbianNetworkUpdater() = default; // -------------------------------------------------------------------------------- // Public methods -HebbianNetworkUpdater::~HebbianNetworkUpdater() { -} +HebbianNetworkUpdater::~HebbianNetworkUpdater() = default; -HebbianNetworkUpdater *HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType instance_type) { +HebbianNetworkUpdater* HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType instance_type) { switch (instance_type) { - case HebbianNetworkUpdaterType:: EXACT_COUNT: { + case HebbianNetworkUpdaterType::EXACT_COUNT: { return new ExactCountHebbianUpdater(); } default: { Utils::error("Invalid HebbianNetworkUpdaterType: " + to_string((int) instance_type)); - return NULL; // to avoid warnings + return nullptr; // to avoid warnings } } - } -ExactCountHebbianUpdater::ExactCountHebbianUpdater() { -} +ExactCountHebbianUpdater::ExactCountHebbianUpdater() = default; -ExactCountHebbianUpdater::~ExactCountHebbianUpdater() { -} +ExactCountHebbianUpdater::~ExactCountHebbianUpdater() = default; -void ExactCountHebbianUpdater::correlation(const dasproto::HandleList *request) { - HebbianNetwork *network = (HebbianNetwork *) request->hebbian_network(); - if (network != NULL) { - for (const string &s: ((dasproto::HandleList *) request)->list()) { +void ExactCountHebbianUpdater::correlation(const dasproto::HandleList* request) { + auto* network = (HebbianNetwork*) request->hebbian_network(); + if (network != nullptr) { + for (const string& s : ((dasproto::HandleList*) request)->list()) { network->add_node(s); } - HebbianNetwork::Node *node1; - HebbianNetwork::Node *node2; - for (const string &s1: ((dasproto::HandleList *) request)->list()) { + HebbianNetwork::Node* node1 = nullptr; + HebbianNetwork::Node* node2 = nullptr; + for (const string& s1 : ((dasproto::HandleList*) request)->list()) { node1 = network->lookup_node(s1); - for (const string &s2: ((dasproto::HandleList *) request)->list()) { + for (const string& s2 : ((dasproto::HandleList*) request)->list()) { if (s1.compare(s2) < 0) { node2 = network->lookup_node(s2); network->add_symmetric_edge(s1, s2, node1, node2); diff --git a/src/attention_broker/HebbianNetworkUpdater.h b/src/attention_broker/HebbianNetworkUpdater.h index 3862052..1f6c056 100644 --- a/src/attention_broker/HebbianNetworkUpdater.h +++ b/src/attention_broker/HebbianNetworkUpdater.h @@ -11,91 +11,94 @@ namespace attention_broker_server { * Algorithm used to update HebbianNetwork weights in "correlate" requests. */ enum class HebbianNetworkUpdaterType { - EXACT_COUNT /// Tracks counts of nodes and links computing actual weights on demand. + EXACT_COUNT /// Tracks counts of nodes and links computing actual weights on + /// demand. }; /** - * Process correlation requests by changing the weights in the passed HebbianNetwork - * to reflect the evidence provided in the request. + * Process correlation requests by changing the weights in the passed + * HebbianNetwork to reflect the evidence provided in the request. * - * Objects of this class are used by worker threads to process "correlation" requests. + * Objects of this class are used by worker threads to process "correlation" + * requests. * - * The request have a list of handles of atoms which appeared together in the same query - * answer. So it's a positive evidence of correlation among such atoms. The HebbianNetwork - * weights are changed to reflect this evidence. + * The request have a list of handles of atoms which appeared together in the + * same query answer. So it's a positive evidence of correlation among such + * atoms. The HebbianNetwork weights are changed to reflect this evidence. * - * This is an abstract class. Concrete subclasses implement different ways of computing - * weights in HebbianNetwork. + * This is an abstract class. Concrete subclasses implement different ways of + * computing weights in HebbianNetwork. */ class HebbianNetworkUpdater { - -public: - + public: /** * Factory method. * - * Factory method to instantiate concrete subclasses according to the passed parameter. + * Factory method to instantiate concrete subclasses according to the passed + * parameter. * * @param instance_type Type of concrete subclass to be instantiated. * * @return An object of the passed type. */ - static HebbianNetworkUpdater *factory(HebbianNetworkUpdaterType instance_type); - virtual ~HebbianNetworkUpdater(); /// Destructor. + static HebbianNetworkUpdater* factory(HebbianNetworkUpdaterType instance_type); + virtual ~HebbianNetworkUpdater(); /// Destructor. /** * Process a correlation evidence. * - * The evidence is used to update the weights in the HebbianNetwork. The actual way these - * weights are updated depends on the type of the concrete subclass that implements this method. + * The evidence is used to update the weights in the HebbianNetwork. The + * actual way these weights are updated depends on the type of the concrete + * subclass that implements this method. * - * @param request A list of handles of atoms which appeared in the same query answer. + * @param request A list of handles of atoms which appeared in the same query + * answer. */ virtual void correlation(const dasproto::HandleList* request) = 0; -protected: - - HebbianNetworkUpdater(); /// Basic empty constructor. - -private: + protected: + HebbianNetworkUpdater(); /// Basic empty constructor. + private: }; /** - * Process correlation requests by changing the weights in the passed HebbianNetwork - * to reflect the evidence provided in the request. + * Process correlation requests by changing the weights in the passed + * HebbianNetwork to reflect the evidence provided in the request. * - * Objects of this class are used by worker threads to process "correlation" requests. + * Objects of this class are used by worker threads to process "correlation" + * requests. * - * The request have a list of handles of atoms which appeared together in the same query - * answer. So it's a positive evidence of correlation among such atoms. The HebbianNetwork - * weights are changed to reflect this evidence. + * The request have a list of handles of atoms which appeared together in the + * same query answer. So it's a positive evidence of correlation among such + * atoms. The HebbianNetwork weights are changed to reflect this evidence. * - * This HebbianNetworkUpdater keeps track of actual counts of atoms and symmetric hebbian - * links between them as they appear in correlation evidence (requests). Actual hebbian weights - * between A -> B are calculated on demand by dividing count(A->B) / count(A). + * This HebbianNetworkUpdater keeps track of actual counts of atoms and + * symmetric hebbian links between them as they appear in correlation evidence + * (requests). Actual hebbian weights between A -> B are calculated on demand by + * dividing count(A->B) / count(A). */ -class ExactCountHebbianUpdater: public HebbianNetworkUpdater { - -public: - - ExactCountHebbianUpdater(); /// Basic empty constructor. - ~ExactCountHebbianUpdater(); /// Destructor. +class ExactCountHebbianUpdater : public HebbianNetworkUpdater { + public: + ExactCountHebbianUpdater(); /// Basic empty constructor. + ~ExactCountHebbianUpdater(); /// Destructor. /** * Process a correlation evidence. * - * The evidence is used to update the weights in the HebbianNetwork. + * The evidence is used to update the weights in the HebbianNetwork. * - * This HebbianNetworkUpdater keeps track of actual counts of atoms and symmetric hebbian - * links between them as they appear in correlation evidence (requests). Actual hebbian weights - * between A -> B are calculated on demand by dividing count(A->B) / count(A). + * This HebbianNetworkUpdater keeps track of actual counts of atoms and + * symmetric hebbian links between them as they appear in correlation evidence + * (requests). Actual hebbian weights between A -> B are calculated on demand + * by dividing count(A->B) / count(A). * - * @param request A list of handles of atoms which appeared in the same query answer. + * @param request A list of handles of atoms which appeared in the same query + * answer. */ - void correlation(const dasproto::HandleList *request); /// Process a correlation evidence. + void correlation(const dasproto::HandleList* request); /// Process a correlation evidence. }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_HEBBIANNETWORKUPDATER_H +#endif // _ATTENTION_BROKER_SERVER_HEBBIANNETWORKUPDATER_H diff --git a/src/attention_broker/RequestSelector.cc b/src/attention_broker/RequestSelector.cc index e589de1..cf49734 100644 --- a/src/attention_broker/RequestSelector.cc +++ b/src/attention_broker/RequestSelector.cc @@ -1,61 +1,47 @@ #include "RequestSelector.h" -#include "Utils.h" + #include +#include "Utils.h" + using namespace attention_broker_server; // -------------------------------------------------------------------------------- // Public methods -RequestSelector::RequestSelector( - unsigned int thread_id, - SharedQueue *stimulus, - SharedQueue *correlation) { +RequestSelector::RequestSelector(unsigned int thread_id, SharedQueue* stimulus, SharedQueue* correlation) + : thread_id(thread_id), stimulus(stimulus), correlation(correlation) {} - this->thread_id = thread_id; - this->stimulus = stimulus; - this->correlation = correlation; -} +RequestSelector::~RequestSelector() = default; -RequestSelector::~RequestSelector() { -} - -EvenThreadCount::EvenThreadCount( - unsigned int thread_id, - SharedQueue *stimulus, - SharedQueue *correlation) : RequestSelector(thread_id, stimulus, correlation) { - - even_thread_id = ((thread_id % 2) == 0); -} - -EvenThreadCount::~EvenThreadCount() { -} +EvenThreadCount::EvenThreadCount(unsigned int thread_id, SharedQueue* stimulus, SharedQueue* correlation) + : RequestSelector(thread_id, stimulus, correlation), even_thread_id((thread_id % 2) == 0) {} -RequestSelector *RequestSelector::factory( - SelectorType instance_type, - unsigned int thread_id, - SharedQueue *stimulus, - SharedQueue *correlation) { +EvenThreadCount::~EvenThreadCount() = default; +RequestSelector* RequestSelector::factory(SelectorType instance_type, + unsigned int thread_id, + SharedQueue* stimulus, + SharedQueue* correlation) { switch (instance_type) { case SelectorType::EVEN_THREAD_COUNT: { return new EvenThreadCount(thread_id, stimulus, correlation); } default: { Utils::error("Invalid selector type: " + to_string((int) instance_type)); - return NULL; // to avoid warnings + return nullptr; // to avoid warnings } } } -pair EvenThreadCount::next() { - pair answer; +pair EvenThreadCount::next() { + pair answer; if (even_thread_id) { answer.first = RequestType::STIMULUS; - answer.second = (void *) stimulus->dequeue(); + answer.second = (void*) stimulus->dequeue(); } else { answer.first = RequestType::CORRELATION; - answer.second = (void *) correlation->dequeue(); + answer.second = (void*) correlation->dequeue(); } return answer; } diff --git a/src/attention_broker/RequestSelector.h b/src/attention_broker/RequestSelector.h index 85aaa36..0c2e8dc 100644 --- a/src/attention_broker/RequestSelector.h +++ b/src/attention_broker/RequestSelector.h @@ -8,31 +8,26 @@ namespace attention_broker_server { using namespace std; using namespace commons; -enum class SelectorType { - EVEN_THREAD_COUNT -}; +enum class SelectorType { EVEN_THREAD_COUNT }; -enum class RequestType { - STIMULUS, - CORRELATION -}; +enum class RequestType { STIMULUS, CORRELATION }; /** - * Abstract class used in WorkerThreads to select the next request to be processed among - * the available request queues. + * Abstract class used in WorkerThreads to select the next request to be + * processed among the available request queues. * - * Concrete subclasses may implement different selection algorithms based in different criteria. + * Concrete subclasses may implement different selection algorithms based in + * different criteria. */ class RequestSelector { - -public: - - virtual ~RequestSelector(); /// Destructor. + public: + virtual ~RequestSelector(); /// Destructor. /** * Factory method. * - * Factory method to instantiate concrete subclasses according to the passed parameter. + * Factory method to instantiate concrete subclasses according to the passed + * parameter. * * @param instance_type Type of concrete subclass to be instantiated. * @param thread_id ID of the thread asking for a new request. @@ -41,53 +36,53 @@ class RequestSelector { * * @return An object of the passed type. */ - static RequestSelector *factory( - SelectorType instance_type, - unsigned int thread_id, - SharedQueue *stimulus, - SharedQueue *correlation); + static RequestSelector* factory(SelectorType instance_type, + unsigned int thread_id, + SharedQueue* stimulus, + SharedQueue* correlation); /** * Return the next request to be processed by the caller worker thread. * * @return the next request to be processed by the caller worker thread. */ - virtual pair next() = 0; + virtual pair next() = 0; -protected: - - RequestSelector(unsigned int thread_id, SharedQueue *stimulus, SharedQueue *correlation); /// Basic constructor. + protected: + RequestSelector(unsigned int thread_id, + SharedQueue* stimulus, + SharedQueue* correlation); /// Basic constructor. unsigned int thread_id; - SharedQueue *stimulus; - SharedQueue *correlation; + SharedQueue* stimulus; + SharedQueue* correlation; }; /** - * Concrete implementation of RequestSelector which evenly distribute worker threads among each type of request. + * Concrete implementation of RequestSelector which evenly distribute worker + * threads among each type of request. * - * This selector keeps half of the working threads working only in "correlate" requests and the other - * half working only in "stimulate" requests. + * This selector keeps half of the working threads working only in "correlate" + * requests and the other half working only in "stimulate" requests. */ class EvenThreadCount : public RequestSelector { - -public: - - ~EvenThreadCount(); /// Destructor. - EvenThreadCount(unsigned int thread_id, SharedQueue *stimulus, SharedQueue *correlation); /// Basic constructor. + public: + ~EvenThreadCount(); /// Destructor. + EvenThreadCount(unsigned int thread_id, + SharedQueue* stimulus, + SharedQueue* correlation); /// Basic constructor. /** * Return the next request to be processed by the caller worker thread. * * @return the next request to be processed by the caller worker thread. */ - pair next(); - -private: + pair next(); + private: bool even_thread_id; }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_REQUESTSELECTOR_H +#endif // _ATTENTION_BROKER_SERVER_REQUESTSELECTOR_H diff --git a/src/attention_broker/StimulusSpreader.cc b/src/attention_broker/StimulusSpreader.cc index d269bc8..b503d70 100644 --- a/src/attention_broker/StimulusSpreader.cc +++ b/src/attention_broker/StimulusSpreader.cc @@ -1,96 +1,90 @@ -#include "expression_hasher.h" #include "StimulusSpreader.h" -#include "HebbianNetwork.h" + +#include +#include + #include "AttentionBrokerServer.h" +#include "HebbianNetwork.h" #include "Utils.h" -#include -#include +#include "expression_hasher.h" using namespace attention_broker_server; // -------------------------------------------------------------------------------- // Public constructors and destructors -StimulusSpreader::~StimulusSpreader() { -} +StimulusSpreader::~StimulusSpreader() = default; -StimulusSpreader::StimulusSpreader() { -} +StimulusSpreader::StimulusSpreader() = default; -StimulusSpreader *StimulusSpreader::factory(StimulusSpreaderType instance_type) { +StimulusSpreader* StimulusSpreader::factory(StimulusSpreaderType instance_type) { switch (instance_type) { - case StimulusSpreaderType::TOKEN : { + case StimulusSpreaderType::TOKEN: { return new TokenSpreader(); } default: { Utils::error("Invalid StimulusSpreaderType: " + to_string((int) instance_type)); - return NULL; // to avoid warnings + return nullptr; // to avoid warnings } } - } -TokenSpreader:: TokenSpreader() { -} +TokenSpreader::TokenSpreader() = default; -TokenSpreader:: ~TokenSpreader() { -} +TokenSpreader::~TokenSpreader() = default; // ------------------------------------------------ // "visit" functions used to traverse network -typedef TokenSpreader::StimuliData DATA; +using DATA = TokenSpreader::StimuliData; -static bool collect_rent(HandleTrie::TrieNode *node, void *data) { - ImportanceType rent = ((DATA *) data)->rent_rate * \ - ((HebbianNetwork::Node *) node->value)->importance; - ((DATA *) data)->total_rent += rent; - ImportanceType wages = 0.0; - ((DATA *) data)->importance_changes->insert( - node->suffix, - new TokenSpreader::ImportanceChanges(rent, wages)); +static bool collect_rent(HandleTrie::TrieNode* node, void* data) { + ImportanceType const rent = + ((DATA*) data)->rent_rate * (dynamic_cast(node->value))->importance; + ((DATA*) data)->total_rent += rent; + ImportanceType const wages = 0.0; + ((DATA*) data) + ->importance_changes->insert(node->suffix, new TokenSpreader::ImportanceChanges(rent, wages)); return false; } -static bool consolidate_rent_and_wages(HandleTrie::TrieNode *node, void *data) { - - HebbianNetwork::Node *value = (HebbianNetwork::Node *) node->value; +static bool consolidate_rent_and_wages(HandleTrie::TrieNode* node, void* data) { + auto* value = dynamic_cast(node->value); - TokenSpreader::ImportanceChanges *changes =\ - (TokenSpreader::ImportanceChanges *) ((DATA *) data)->importance_changes->lookup(node->suffix); + auto* changes = dynamic_cast( + ((DATA*) data)->importance_changes->lookup(node->suffix)); value->importance -= changes->rent; value->importance += changes->wages; // Compute amount to be spread - ImportanceType arity_ratio = (double) value->arity / ((DATA *) data)->largest_arity; - ImportanceType spreading_rate = ((DATA *) data)->spreading_rate_lowerbound + \ - (((DATA *) data)->spreading_rate_range_size * \ - arity_ratio); - ImportanceType to_spread = value->importance * spreading_rate; + ImportanceType const arity_ratio = (double) value->arity / ((DATA*) data)->largest_arity; + ImportanceType const spreading_rate = ((DATA*) data)->spreading_rate_lowerbound + + (((DATA*) data)->spreading_rate_range_size * arity_ratio); + ImportanceType const to_spread = value->importance * spreading_rate; value->importance -= to_spread; value->stimuli_to_spread = to_spread; return false; } -static bool sum_weights(HandleTrie::TrieNode *node, void *data) { - HebbianNetwork::Edge *edge = (HebbianNetwork::Edge *) node->value; - double w = (double) edge->count / edge->node1->count; - ((DATA *) data)->sum_weights += w; +static bool sum_weights(HandleTrie::TrieNode* node, void* data) { + auto* edge = dynamic_cast(node->value); + double const w = (double) edge->count / edge->node1->count; + ((DATA*) data)->sum_weights += w; return false; } -static bool deliver_stimulus(HandleTrie::TrieNode *node, void *data) { - HebbianNetwork::Edge *edge = (HebbianNetwork::Edge *) node->value; - double w = (double) edge->count / edge->node1->count; - ImportanceType stimulus = (w / ((DATA *) data)->sum_weights) * ((DATA *) data)->to_spread; +static bool deliver_stimulus(HandleTrie::TrieNode* node, void* data) { + auto* edge = dynamic_cast(node->value); + double const w = (double) edge->count / edge->node1->count; + ImportanceType const stimulus = (w / ((DATA*) data)->sum_weights) * ((DATA*) data)->to_spread; edge->node2->importance += stimulus; return false; } -static bool consolidate_stimulus(HandleTrie::TrieNode *node, void *data) { - HebbianNetwork::Node *value = (HebbianNetwork::Node *) node->value; - ((DATA *) data)->to_spread = value->stimuli_to_spread; - ((DATA *) data)->sum_weights = 0.0; +static bool consolidate_stimulus(HandleTrie::TrieNode* node, void* data) { + auto* value = dynamic_cast(node->value); + ((DATA*) data)->to_spread = value->stimuli_to_spread; + ((DATA*) data)->sum_weights = 0.0; value->neighbors->traverse(true, &sum_weights, data); value->neighbors->traverse(true, &deliver_stimulus, data); value->stimuli_to_spread = 0.0; @@ -100,28 +94,26 @@ static bool consolidate_stimulus(HandleTrie::TrieNode *node, void *data) { // ------------------------------------------------ // Public methods -void TokenSpreader::distribute_wages( - const dasproto::HandleCount *handle_count, - ImportanceType &total_to_spread, - DATA *data) { - +void TokenSpreader::distribute_wages(const dasproto::HandleCount* handle_count, + ImportanceType& total_to_spread, + DATA* data) { auto iterator = handle_count->map().find("SUM"); if (iterator == handle_count->map().end()) { Utils::error("Missing 'SUM' key in HandleCount request"); } - unsigned int total_wages = iterator->second; - for (auto pair: handle_count->map()) { + unsigned int const total_wages = iterator->second; + for (const auto& pair : handle_count->map()) { if (pair.first != "SUM") { - double normalized_amount = (((double) pair.second) * total_to_spread) / total_wages; - data->importance_changes->insert(pair.first, new TokenSpreader::ImportanceChanges(0.0, normalized_amount)); + double const normalized_amount = (((double) pair.second) * total_to_spread) / total_wages; + data->importance_changes->insert( + pair.first, new TokenSpreader::ImportanceChanges(0.0, normalized_amount)); } } } -void TokenSpreader::spread_stimuli(const dasproto::HandleCount *request) { - - HebbianNetwork *network = (HebbianNetwork *) request->hebbian_network(); - if (network == NULL) { +void TokenSpreader::spread_stimuli(const dasproto::HandleCount* request) { + auto* network = (HebbianNetwork*) request->hebbian_network(); + if (network == nullptr) { return; } @@ -129,13 +121,13 @@ void TokenSpreader::spread_stimuli(const dasproto::HandleCount *request) { data.importance_changes = new HandleTrie(HANDLE_HASH_SIZE - 1); data.rent_rate = AttentionBrokerServer::RENT_RATE; data.spreading_rate_lowerbound = AttentionBrokerServer::SPREADING_RATE_LOWERBOUND; - data.spreading_rate_range_size = \ - AttentionBrokerServer::SPREADING_RATE_UPPERBOUND - AttentionBrokerServer::SPREADING_RATE_LOWERBOUND; + data.spreading_rate_range_size = AttentionBrokerServer::SPREADING_RATE_UPPERBOUND - + AttentionBrokerServer::SPREADING_RATE_LOWERBOUND; data.largest_arity = network->largest_arity; data.total_rent = 0.0; // Collect rent - network->visit_nodes(true, &collect_rent, (void *) &data); + network->visit_nodes(true, &collect_rent, (void*) &data); // Distribute wages ImportanceType total_to_spread = network->alienate_tokens(); @@ -143,7 +135,7 @@ void TokenSpreader::spread_stimuli(const dasproto::HandleCount *request) { distribute_wages(request, total_to_spread, &data); // Consolidate changes - network->visit_nodes(true, &consolidate_rent_and_wages, (void *) &data); + network->visit_nodes(true, &consolidate_rent_and_wages, (void*) &data); // Spread activation (1 cycle) network->visit_nodes(true, &consolidate_stimulus, &data); diff --git a/src/attention_broker/StimulusSpreader.h b/src/attention_broker/StimulusSpreader.h index 5a9ae2e..be413a3 100644 --- a/src/attention_broker/StimulusSpreader.h +++ b/src/attention_broker/StimulusSpreader.h @@ -1,9 +1,9 @@ #ifndef _ATTENTION_BROKER_SERVER_STIMULUSSPREADER_H #define _ATTENTION_BROKER_SERVER_STIMULUSSPREADER_H -#include "attention_broker.grpc.pb.h" -#include "Utils.h" #include "HebbianNetwork.h" +#include "Utils.h" +#include "attention_broker.grpc.pb.h" using namespace std; @@ -13,86 +13,88 @@ namespace attention_broker_server { * Algorithm used to update HebbianNetwork weights in "stimulate" requests. */ enum class StimulusSpreaderType { - TOKEN /// Consider importance as a fixed amount of tokens distributed among atoms in the HebbianNetwork. + TOKEN /// Consider importance as a fixed amount of tokens distributed among + /// atoms in the HebbianNetwork. }; /** - * Process stimuli spreading requests by boosting importance of the atoms passed in the request - * and running one cycle of stimuli spreading in the Hebbian Network. + * Process stimuli spreading requests by boosting importance of the atoms passed + * in the request and running one cycle of stimuli spreading in the Hebbian + * Network. + * + * Objects of this class are used by worker threads to process "stimulate" + * requests. * - * Objects of this class are used by worker threads to process "stimulate" requests. + * The request have a list of pairs (handle, n) with the handles whose + * importance should be boosted and the relative magnitude of this boost + * (compared to the other handles in the same request). * - * The request have a list of pairs (handle, n) with the handles whose importance should be - * boosted and the relative magnitude of this boost (compared to the other handles in the same - * request). + * This is an abstract class. Concrete subclasses implement different ways of + * spreading stimuli in the HebbianNetwork. * - * This is an abstract class. Concrete subclasses implement different ways of spreading stimuli - * in the HebbianNetwork. - * */ class StimulusSpreader { - -public: - + public: /** * Factory method. * - * Factory method to instantiate concrete subclasses according to the passed parameter. + * Factory method to instantiate concrete subclasses according to the passed + * parameter. * * @param instance_type Type of concrete subclass to be instantiated. * * @return An object of the passed type. */ - static StimulusSpreader *factory(StimulusSpreaderType instance_type); - virtual ~StimulusSpreader(); /// destructor. + static StimulusSpreader* factory(StimulusSpreaderType instance_type); + virtual ~StimulusSpreader(); /// destructor. /** * Stimulate atoms and run one cycle of stimuli spreading. * - * Atoms in the passed list have their importance boosted according to the passed counts. Then - * one cycle of stimuli spreading is executed. + * Atoms in the passed list have their importance boosted according to the + * passed counts. Then one cycle of stimuli spreading is executed. * - * @param request A list of handles to be boosted and respective counts which are used to determine - * the magnitude of such boost. The actual way importance is boosted and then spread among HebbianNetwork - * links are delegated to the concrete subclasses. + * @param request A list of handles to be boosted and respective counts which + * are used to determine the magnitude of such boost. The actual way + * importance is boosted and then spread among HebbianNetwork links are + * delegated to the concrete subclasses. */ - virtual void spread_stimuli(const dasproto::HandleCount *request) = 0; - -protected: - - StimulusSpreader(); /// Basic empty constructor. + virtual void spread_stimuli(const dasproto::HandleCount* request) = 0; -private: + protected: + StimulusSpreader(); /// Basic empty constructor. + private: }; /** - * Process stimuli spreading requests by boosting importance of the atoms passed in the request - * and running one cycle of stimuli spreading in the Hebbian Network. + * Process stimuli spreading requests by boosting importance of the atoms passed + * in the request and running one cycle of stimuli spreading in the Hebbian + * Network. * - * Objects of this class are used by worker threads to process "stimulate" requests. + * Objects of this class are used by worker threads to process "stimulate" + * requests. * - * The request have a list of pairs (handle, n) with the handles whose importance should be - * boosted and the relative magnitude of this boost (compared to the other handles in the same - * request). + * The request have a list of pairs (handle, n) with the handles whose + * importance should be boosted and the relative magnitude of this boost + * (compared to the other handles in the same request). * - * This StimulusSpreader consider a fixed amount of tokens distributed among all atoms in the - * HebbianNetwork. Importance boosts and stimulus spreading are implemented in a way that this - * total amount of tokens remains fixed, unless explicitly requested by caller. + * This StimulusSpreader consider a fixed amount of tokens distributed among all + * atoms in the HebbianNetwork. Importance boosts and stimulus spreading are + * implemented in a way that this total amount of tokens remains fixed, unless + * explicitly requested by caller. */ -class TokenSpreader: public StimulusSpreader { - -public: - - TokenSpreader(); /// Basic empty constructor. - ~TokenSpreader(); /// Destructor. +class TokenSpreader : public StimulusSpreader { + public: + TokenSpreader(); /// Basic empty constructor. + ~TokenSpreader(); /// Destructor. // data structure used as parameter container in "visit" functions // used in trie traversal typedef struct { ImportanceType rent_rate; ImportanceType total_rent; - HandleTrie *importance_changes; + HandleTrie* importance_changes; unsigned int largest_arity; ImportanceType spreading_rate_lowerbound; ImportanceType spreading_rate_range_size; @@ -101,43 +103,45 @@ class TokenSpreader: public StimulusSpreader { } StimuliData; // data structure used in a private trie during importance update calculations - class ImportanceChanges: public HandleTrie::TrieValue { - public: - ImportanceType rent; - ImportanceType wages; - ImportanceChanges(ImportanceType r, ImportanceType w) { - rent = r; - wages = w; - } - void merge(TrieValue *other) { - rent += ((ImportanceChanges *) other)->rent; - wages += ((ImportanceChanges *) other)->wages; - } + class ImportanceChanges : public HandleTrie::TrieValue { + public: + ImportanceType rent; + ImportanceType wages; + ImportanceChanges(ImportanceType r, ImportanceType w) { + rent = r; + wages = w; + } + void merge(TrieValue* other) { + rent += ((ImportanceChanges*) other)->rent; + wages += ((ImportanceChanges*) other)->wages; + } }; /** * Stimulate atoms and run one cycle of stimuli spreading. * - * Atoms in the passed list have their importance boosted according to the passed counts. Then - * one cycle of stimuli spreading is executed. + * Atoms in the passed list have their importance boosted according to the + * passed counts. Then one cycle of stimuli spreading is executed. * - * Boosts and stimuli spreading are actually tokens which are collected from all the nodes in the - * HebbianNetwork (as a rent) and redistributed according to the passed * counts (as wages). Once - * rents and wages are consolidated in each node's importance, one cycle of stimuli spreading is run - * when a % of the importance tokens of each node being redistributed to amnongst its neighbors - * according to the weights of the links in the HebbianNetwork. + * Boosts and stimuli spreading are actually tokens which are collected from + * all the nodes in the HebbianNetwork (as a rent) and redistributed according + * to the passed * counts (as wages). Once rents and wages are consolidated in + * each node's importance, one cycle of stimuli spreading is run when a % of + * the importance tokens of each node being redistributed to amnongst its + * neighbors according to the weights of the links in the HebbianNetwork. * - * @param request A list of handles to be boosted and respective counts which are used to determine - * the magnitude of such boost. + * @param request A list of handles to be boosted and respective counts which + * are used to determine the magnitude of such boost. */ - void spread_stimuli(const dasproto::HandleCount *request); - - // Used only in "visit" functions during trie traversals. Such functions aren't methods so this method - // must be public. - void distribute_wages(const dasproto::HandleCount *handle_count, ImportanceType &total_to_spread, StimuliData *data); + void spread_stimuli(const dasproto::HandleCount* request); + // Used only in "visit" functions during trie traversals. Such functions + // aren't methods so this method must be public. + void distribute_wages(const dasproto::HandleCount* handle_count, + ImportanceType& total_to_spread, + StimuliData* data); }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_STIMULUSSPREADER_H +#endif // _ATTENTION_BROKER_SERVER_STIMULUSSPREADER_H diff --git a/src/attention_broker/WorkerThreads.cc b/src/attention_broker/WorkerThreads.cc index 90020eb..cc06641 100644 --- a/src/attention_broker/WorkerThreads.cc +++ b/src/attention_broker/WorkerThreads.cc @@ -1,12 +1,13 @@ +#include "WorkerThreads.h" + #include #include "AttentionBrokerServer.h" -#include "attention_broker.grpc.pb.h" -#include "Utils.h" -#include "RequestSelector.h" -#include "WorkerThreads.h" #include "HebbianNetworkUpdater.h" +#include "RequestSelector.h" #include "StimulusSpreader.h" +#include "Utils.h" +#include "attention_broker.grpc.pb.h" using namespace attention_broker_server; using namespace std; @@ -14,59 +15,50 @@ using namespace std; // -------------------------------------------------------------------------------- // Public methods -WorkerThreads::WorkerThreads(SharedQueue *stimulus, SharedQueue *correlation) { - stimulus_requests = stimulus; - correlation_requests = correlation; - threads_count = AttentionBrokerServer::WORKER_THREADS_COUNT; +WorkerThreads::WorkerThreads(SharedQueue* stimulus, SharedQueue* correlation) + : stimulus_requests(stimulus), + correlation_requests(correlation), + threads_count(AttentionBrokerServer::WORKER_THREADS_COUNT) { for (unsigned int i = 0; i < threads_count; i++) { - threads.push_back(new thread( - &WorkerThreads::worker_thread, - this, - i, - stimulus_requests, - correlation_requests)); + threads.push_back( + new thread(&WorkerThreads::worker_thread, this, i, stimulus_requests, correlation_requests)); } } -WorkerThreads::~WorkerThreads() { -} +WorkerThreads::~WorkerThreads() = default; void WorkerThreads::graceful_stop() { stop_flag_mutex.lock(); stop_flag = true; stop_flag_mutex.unlock(); - for (thread *worker_thread: threads) { + for (thread* worker_thread : threads) { worker_thread->join(); } } - + // -------------------------------------------------------------------------------- // Private methods -void WorkerThreads::worker_thread( - unsigned int thread_id, - SharedQueue *stimulus_requests, - SharedQueue *correlation_requests) { - - RequestSelector *selector = RequestSelector::factory( - SelectorType::EVEN_THREAD_COUNT, - thread_id, - stimulus_requests, - correlation_requests); - HebbianNetworkUpdater *updater = HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); - StimulusSpreader *stimulus_spreader = StimulusSpreader::factory(StimulusSpreaderType::TOKEN); - pair request; +void WorkerThreads::worker_thread(unsigned int thread_id, + SharedQueue* stimulus_requests, + SharedQueue* correlation_requests) { + RequestSelector* selector = RequestSelector::factory( + SelectorType::EVEN_THREAD_COUNT, thread_id, stimulus_requests, correlation_requests); + HebbianNetworkUpdater* updater = + HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); + StimulusSpreader* stimulus_spreader = StimulusSpreader::factory(StimulusSpreaderType::TOKEN); + pair request; bool stop = false; - while (! stop) { + while (!stop) { request = selector->next(); if (request.second != NULL) { switch (request.first) { case RequestType::STIMULUS: { - stimulus_spreader->spread_stimuli((dasproto::HandleCount *) request.second); + stimulus_spreader->spread_stimuli((dasproto::HandleCount*) request.second); break; } case RequestType::CORRELATION: { - updater->correlation((dasproto::HandleList *) request.second); + updater->correlation((dasproto::HandleList*) request.second); break; } default: { diff --git a/src/attention_broker/WorkerThreads.h b/src/attention_broker/WorkerThreads.h index 38c429f..c1869ae 100644 --- a/src/attention_broker/WorkerThreads.h +++ b/src/attention_broker/WorkerThreads.h @@ -1,11 +1,11 @@ #ifndef _ATTENTION_BROKER_SERVER_WORKERTHREADS_H #define _ATTENTION_BROKER_SERVER_WORKERTHREADS_H -#include #include +#include +#include #include #include -#include #include "SharedQueue.h" @@ -17,50 +17,49 @@ namespace attention_broker_server { /** * Used in AttentionBrokerServer to keep track of worker threads. * - * WorkerThreads provides an abstraction to actual threads creation and shutdown. + * WorkerThreads provides an abstraction to actual threads creation and + * shutdown. */ class WorkerThreads { - -public: - + public: /** * Constructor. * - * Start n worker threads (n is a parameter defined in AttentionBrokerServer) and - * keep then running getting requests from the queues which have been passed as - * parameters. + * Start n worker threads (n is a parameter defined in AttentionBrokerServer) + * and keep then running getting requests from the queues which have been + * passed as parameters. * - * Working threads can process any type of requests. The policy of which request - * queue a worker thread will read from next is determined by RequestSelector. + * Working threads can process any type of requests. The policy of which + * request queue a worker thread will read from next is determined by + * RequestSelector. */ - WorkerThreads(SharedQueue *stimulus, SharedQueue *correlation); - ~WorkerThreads(); /// Destructor. + WorkerThreads(SharedQueue* stimulus, SharedQueue* correlation); + ~WorkerThreads(); /// Destructor. /** * Gracefully and synchronously stop all threads. * - * Sets a flag which is check by each thread when the requests queue are empty. It means - * that both requests queues will be processed before the threads actually stop. When - * both requests queues are empty, threads return and are destroyed. This method will wait - * for all threads to finish before returning. + * Sets a flag which is check by each thread when the requests queue are + * empty. It means that both requests queues will be processed before the + * threads actually stop. When both requests queues are empty, threads return + * and are destroyed. This method will wait for all threads to finish before + * returning. */ void graceful_stop(); -private: - + private: unsigned int threads_count; - vector threads; + vector threads; bool stop_flag = false; - SharedQueue *stimulus_requests; - SharedQueue *correlation_requests; + SharedQueue* stimulus_requests; + SharedQueue* correlation_requests; mutex stop_flag_mutex; - void worker_thread( - unsigned int thread_id, - SharedQueue *stimulus_requests, - SharedQueue *correlation_requests); + void worker_thread(unsigned int thread_id, + SharedQueue* stimulus_requests, + SharedQueue* correlation_requests); }; -} // namespace attention_broker_server +} // namespace attention_broker_server -#endif // _ATTENTION_BROKER_SERVER_WORKERTHREADS_H +#endif // _ATTENTION_BROKER_SERVER_WORKERTHREADS_H diff --git a/src/commons/SharedQueue.cc b/src/commons/SharedQueue.cc index bea0575..f26154f 100644 --- a/src/commons/SharedQueue.cc +++ b/src/commons/SharedQueue.cc @@ -13,9 +13,7 @@ SharedQueue::SharedQueue(unsigned int initial_size) { end = 0; } -SharedQueue::~SharedQueue() { - delete [] requests; -} +SharedQueue::~SharedQueue() { delete[] requests; } bool SharedQueue::empty() { bool answer; @@ -25,7 +23,7 @@ bool SharedQueue::empty() { return answer; } -void SharedQueue::enqueue(void *request) { +void SharedQueue::enqueue(void* request) { shared_queue_mutex.lock(); if (count == size) { enlarge_shared_queue(); @@ -36,8 +34,8 @@ void SharedQueue::enqueue(void *request) { shared_queue_mutex.unlock(); } -void *SharedQueue::dequeue() { - void *answer = NULL; +void* SharedQueue::dequeue() { + void* answer = NULL; shared_queue_mutex.lock(); if (count > 0) { answer = requests[start]; @@ -51,28 +49,20 @@ void *SharedQueue::dequeue() { // -------------------------------------------------------------------------------- // Protected methods -unsigned int SharedQueue::current_size() { - return size; -} +unsigned int SharedQueue::current_size() { return size; } -unsigned int SharedQueue::current_start() { - return start; -} +unsigned int SharedQueue::current_start() { return start; } -unsigned int SharedQueue::current_end() { - return end; -} +unsigned int SharedQueue::current_end() { return end; } -unsigned int SharedQueue::current_count() { - return count; -} +unsigned int SharedQueue::current_count() { return count; } // -------------------------------------------------------------------------------- // Private methods void SharedQueue::enlarge_shared_queue() { unsigned int _new_size = size * 2; - void **_new_queue = new void*[_new_size]; + void** _new_queue = new void*[_new_size]; unsigned int _cursor = start; unsigned int _new_cursor = 0; do { @@ -82,7 +72,7 @@ void SharedQueue::enlarge_shared_queue() { size = _new_size; start = 0; end = _new_cursor; - delete [] requests; + delete[] requests; requests = _new_queue; // count remains unchanged } diff --git a/src/commons/SharedQueue.h b/src/commons/SharedQueue.h index 41b0b03..07a74dc 100644 --- a/src/commons/SharedQueue.h +++ b/src/commons/SharedQueue.h @@ -6,52 +6,51 @@ namespace commons { /** - * Data abstraction of a synchronized (thread-safe) queue for assynchronous requests. + * Data abstraction of a synchronized (thread-safe) queue for assynchronous + * requests. * - * Internally, this abstraction uses an array of requests to avoid the need to create cell - * objects on every insertion. Because of this, on new insertions it's possible to reach queue - * size limit during an insertion. When that happens, the array is doubled in size. Initial size - * is passed as a constructor's parameter. + * Internally, this abstraction uses an array of requests to avoid the need to + * create cell objects on every insertion. Because of this, on new insertions + * it's possible to reach queue size limit during an insertion. When that + * happens, the array is doubled in size. Initial size is passed as a + * constructor's parameter. */ class SharedQueue { + public: + SharedQueue(unsigned int initial_size = 1000); // Basic constructor -public: - - SharedQueue(unsigned int initial_size = 1000); // Basic constructor - - ~SharedQueue(); /// Destructor. + ~SharedQueue(); /// Destructor. /** * Enqueues a request. * * @param request Request to be queued. */ - void enqueue(void *request); + void enqueue(void* request); /** * Dequeues a request. * * @return The dequeued request. */ - void *dequeue(); + void* dequeue(); /** * Returns true iff the queue is empty. */ bool empty(); -protected: - + protected: unsigned int current_size(); unsigned int current_start(); unsigned int current_end(); unsigned int current_count(); -private: - + private: std::mutex shared_queue_mutex; - void **requests; // GRPC documentation states that request types should not be inherited + void** requests; // GRPC documentation states that request types should not be + // inherited unsigned int size; unsigned int count; unsigned int start; @@ -60,6 +59,6 @@ class SharedQueue { void enlarge_shared_queue(); }; -} // namespace commons +} // namespace commons -#endif // _COMMONS_SHAREDQUEUE_H +#endif // _COMMONS_SHAREDQUEUE_H diff --git a/src/commons/Utils.cc b/src/commons/Utils.cc index 2210002..3915360 100644 --- a/src/commons/Utils.cc +++ b/src/commons/Utils.cc @@ -1,31 +1,25 @@ -#include +#include "Utils.h" + #include -#include -#include +#include #include +#include #include +#include #include -#include "Utils.h" - using namespace commons; using namespace std; // -------------------------------------------------------------------------------- // Public methods -Utils::Utils() { -} +Utils::Utils() {} -Utils::~Utils() { -} +Utils::~Utils() {} -void Utils::error(string msg) { - throw runtime_error(msg); -} -void Utils::warning(string msg) { - cerr << msg << endl; -} +void Utils::error(string msg) { throw runtime_error(msg); } +void Utils::warning(string msg) { cerr << msg << endl; } bool Utils::flip_coin(double true_probability) { long f = 1000; @@ -36,18 +30,15 @@ void Utils::sleep(unsigned int milliseconds) { this_thread::sleep_for(chrono::milliseconds(milliseconds)); } -string Utils::get_environment(string const &key) { - char *value = getenv(key.c_str()); +string Utils::get_environment(string const& key) { + char* value = getenv(key.c_str()); string answer = (value == NULL ? "" : value); return answer; } -StopWatch::StopWatch() { - reset(); -} +StopWatch::StopWatch() { reset(); } -StopWatch::~StopWatch() { -} +StopWatch::~StopWatch() {} void StopWatch::start() { if (running) { @@ -76,7 +67,6 @@ unsigned long StopWatch::milliseconds() { } string StopWatch::str_time() { - unsigned long millis = milliseconds(); unsigned long seconds = millis / 1000; @@ -93,10 +83,10 @@ string StopWatch::str_time() { } else if (minutes > 0) { return to_string(minutes) + " mins " + to_string(seconds) + " secs"; } else if (seconds > 0) { - //double s = ((double) ((seconds * 1000) + millis)) / 1000.0; - //std::stringstream stream; - //stream << std::fixed << std::setprecision(3) << s; - //return stream.str() + " secs"; + // double s = ((double) ((seconds * 1000) + millis)) / 1000.0; + // std::stringstream stream; + // stream << std::fixed << std::setprecision(3) << s; + // return stream.str() + " secs"; return to_string(seconds) + " secs " + to_string(millis) + " millis"; } else { return to_string(millis) + " millis"; diff --git a/src/commons/Utils.h b/src/commons/Utils.h index 4230dbc..1f4a142 100644 --- a/src/commons/Utils.h +++ b/src/commons/Utils.h @@ -1,32 +1,31 @@ #ifndef _COMMONS_UTILS_H #define _COMMONS_UTILS_H -#include #include +#include using namespace std; namespace commons { class StopWatch { - public: - StopWatch(); - ~StopWatch(); - void start(); - void stop(); - void reset(); - unsigned long milliseconds(); - string str_time(); - private: - bool running; - chrono::steady_clock::time_point start_time; - chrono::steady_clock::duration accumulator; + public: + StopWatch(); + ~StopWatch(); + void start(); + void stop(); + void reset(); + unsigned long milliseconds(); + string str_time(); + + private: + bool running; + chrono::steady_clock::time_point start_time; + chrono::steady_clock::duration accumulator; }; class Utils { - -public: - + public: Utils(); ~Utils(); @@ -34,9 +33,9 @@ class Utils { static void warning(string msg); static bool flip_coin(double true_probability = 0.5); static void sleep(unsigned int milliseconds = 100); - static string get_environment(string const &key); + static string get_environment(string const& key); }; -} // namespace commons +} // namespace commons -#endif // _COMMONS_UTILS_H +#endif // _COMMONS_UTILS_H diff --git a/src/distributed_algorithm_node/DistributedAlgorithmNode.cc b/src/distributed_algorithm_node/DistributedAlgorithmNode.cc index dcd576f..0500e26 100644 --- a/src/distributed_algorithm_node/DistributedAlgorithmNode.cc +++ b/src/distributed_algorithm_node/DistributedAlgorithmNode.cc @@ -1,26 +1,23 @@ #include "DistributedAlgorithmNode.h" + #include "Utils.h" using namespace distributed_algorithm_node; using namespace commons; -DistributedAlgorithmNode::DistributedAlgorithmNode( - const string &node_id, - LeadershipBrokerType leadership_algorithm, - MessageBrokerType messaging_backend) { - +DistributedAlgorithmNode::DistributedAlgorithmNode(const string& node_id, + LeadershipBrokerType leadership_algorithm, + MessageBrokerType messaging_backend) { this->my_node_id = node_id; this->leadership_broker = LeadershipBroker::factory(leadership_algorithm); - this->message_broker = MessageBroker::factory( - messaging_backend, - // Empty destructor to avoid node deletion - shared_ptr(this, [](MessageFactory *) {}), - node_id); + this->message_broker = + MessageBroker::factory(messaging_backend, + // Empty destructor to avoid node deletion + shared_ptr(this, [](MessageFactory*) {}), + node_id); } -DistributedAlgorithmNode::~DistributedAlgorithmNode() { - this->graceful_shutdown(); -} +DistributedAlgorithmNode::~DistributedAlgorithmNode() { this->graceful_shutdown(); } // ------------------------------------------------------------------------------------------------- // Public API @@ -28,10 +25,10 @@ DistributedAlgorithmNode::~DistributedAlgorithmNode() { void DistributedAlgorithmNode::join_network() { this->leadership_broker->set_message_broker(this->message_broker); this->message_broker->join_network(); - //Utils::sleep(1000); + // Utils::sleep(1000); string my_leadership_vote = this->cast_leadership_vote(); this->leadership_broker->start_leader_election(my_leadership_vote); - while (! this->has_leader()) { + while (!this->has_leader()) { Utils::sleep(); } vector args; @@ -39,39 +36,30 @@ void DistributedAlgorithmNode::join_network() { this->message_broker->broadcast(this->known_commands.NODE_JOINED_NETWORK, args); } -bool DistributedAlgorithmNode::is_leader() { - return (this->leader_id() == this->node_id()); -} +bool DistributedAlgorithmNode::is_leader() { return (this->leader_id() == this->node_id()); } -string DistributedAlgorithmNode::leader_id() { - return this->leadership_broker->leader_id(); -} +string DistributedAlgorithmNode::leader_id() { return this->leadership_broker->leader_id(); } -bool DistributedAlgorithmNode::has_leader() { - return this->leadership_broker->has_leader(); -} +bool DistributedAlgorithmNode::has_leader() { return this->leadership_broker->has_leader(); } -void DistributedAlgorithmNode::add_peer(const string &peer_id) { +void DistributedAlgorithmNode::add_peer(const string& peer_id) { this->message_broker->add_peer(peer_id); } -string DistributedAlgorithmNode::node_id() { - return this->my_node_id; -} +string DistributedAlgorithmNode::node_id() { return this->my_node_id; } -void DistributedAlgorithmNode::broadcast(const string &command, const vector &args) { +void DistributedAlgorithmNode::broadcast(const string& command, const vector& args) { this->message_broker->broadcast(command, args); } -void DistributedAlgorithmNode::send( - const string &command, - const vector &args, - const string &recipient) { - +void DistributedAlgorithmNode::send(const string& command, + const vector& args, + const string& recipient) { this->message_broker->send(command, args, recipient); } -std::shared_ptr DistributedAlgorithmNode::message_factory(string &command, vector &args) { +std::shared_ptr DistributedAlgorithmNode::message_factory(string& command, + vector& args) { if (command == this->known_commands.NODE_JOINED_NETWORK) { return std::shared_ptr(new NodeJoinedNetwork(args[0])); } else { @@ -79,6 +67,4 @@ std::shared_ptr DistributedAlgorithmNode::message_factory(string &comma } } -void DistributedAlgorithmNode::graceful_shutdown() { - this->message_broker->graceful_shutdown(); -} +void DistributedAlgorithmNode::graceful_shutdown() { this->message_broker->graceful_shutdown(); } diff --git a/src/distributed_algorithm_node/DistributedAlgorithmNode.h b/src/distributed_algorithm_node/DistributedAlgorithmNode.h index 5c0e6d4..893ce90 100644 --- a/src/distributed_algorithm_node/DistributedAlgorithmNode.h +++ b/src/distributed_algorithm_node/DistributedAlgorithmNode.h @@ -1,12 +1,13 @@ #ifndef _DISTRIBUTED_ALGORITHM_NODE_DISTRIBUTEDALGORITHMNODE_H #define _DISTRIBUTED_ALGORITHM_NODE_DISTRIBUTEDALGORITHMNODE_H -#include "LeadershipBroker.h" -#include "MessageBroker.h" -#include "Message.h" #include #include +#include "LeadershipBroker.h" +#include "Message.h" +#include "MessageBroker.h" + using namespace std; namespace distributed_algorithm_node { @@ -14,44 +15,47 @@ namespace distributed_algorithm_node { /** * Implements a node in a network used for some distributed processing. * - * This is an abstract class so users of this module are supposed to extend it to - * implement its own distributed network. + * This is an abstract class so users of this module are supposed to extend it + * to implement its own distributed network. * * Communication between nodes are performed by Message objects which are like * a piece of code sent from one node to another. We don't actually send * code but instead we send a reference to what type of Message object is being - * exchanged so once the message arrive in the recipient a Message object is built - * and its code is executed. The "reference" about what type of Message is being - * exchanged is encoded like command lines with commands and its arguments. + * exchanged so once the message arrive in the recipient a Message object is + * built and its code is executed. The "reference" about what type of Message is + * being exchanged is encoded like command lines with commands and its + * arguments. * * This is what you should care about when extending DistributedAlgorithmNode: * - * - DistributedAlgorithmNode is the class that build Message objects. That's why it extends - * MessageFactory. This abstract class already knows how to build some basic Message - * objects for some commands which are common to all the networks (e.g. joining - * of new nodes to the network) but subclasses of DistributedAlgorithmNode should re-implement - * message_factory() to build Message objects for its own distributed application. - * - Message commands are executed in separated threads. So if such commands updates some - * state variable inside DistributedAlgorithmNode or its subclasses, this state variable should - * be protected by mutual exclusion primitives. - * - DistributedAlgorithmNode's constructor expects allocated objects for MessageBroker and - * LeadershipBroker. These are abstract classes which may have many concrete - * implementations. When designing your distributed network you need to decide - * which messaging system is supposed to be used to actually make the communication - * bwtween nodes. You can use one of the concrete implementations we provide or you - * can provide your own implementation extending these abstract classes. Typically, users - * wouldn't need to implement its own messaging system but it may be the case for the - * leadership election algorithm as this is highly dependent on the network topology - * and expected behaviour. - * - DistributedAlgorithmNode has some pure virtual methods that need to be implemented. These are - * the methods called by basic Message objects to acomplish basic tasks like leadership - * election and notification of new nodes joning the network. The proper way to respond - * to these requests are delegated to concrete classes extending DistributedAlgorithmNode. + * - DistributedAlgorithmNode is the class that build Message objects. That's + * why it extends MessageFactory. This abstract class already knows how to build + * some basic Message objects for some commands which are common to all the + * networks (e.g. joining of new nodes to the network) but subclasses of + * DistributedAlgorithmNode should re-implement message_factory() to build + * Message objects for its own distributed application. + * - Message commands are executed in separated threads. So if such commands + * updates some state variable inside DistributedAlgorithmNode or its + * subclasses, this state variable should be protected by mutual exclusion + * primitives. + * - DistributedAlgorithmNode's constructor expects allocated objects for + * MessageBroker and LeadershipBroker. These are abstract classes which may have + * many concrete implementations. When designing your distributed network you + * need to decide which messaging system is supposed to be used to actually make + * the communication bwtween nodes. You can use one of the concrete + * implementations we provide or you can provide your own implementation + * extending these abstract classes. Typically, users wouldn't need to implement + * its own messaging system but it may be the case for the leadership election + * algorithm as this is highly dependent on the network topology and expected + * behaviour. + * - DistributedAlgorithmNode has some pure virtual methods that need to be + * implemented. These are the methods called by basic Message objects to + * acomplish basic tasks like leadership election and notification of new nodes + * joning the network. The proper way to respond to these requests are delegated + * to concrete classes extending DistributedAlgorithmNode. */ class DistributedAlgorithmNode : public MessageFactory { - -public: - + public: /** * Destructor. */ @@ -60,16 +64,15 @@ class DistributedAlgorithmNode : public MessageFactory { /** * Basic constructor. * - * @param node_id The ID of this node. Typically is a string to identify this node - * in the MessageBroker. - * @param leadership_algorithm The concrete class to be used as leadership broker. + * @param node_id The ID of this node. Typically is a string to identify this + * node in the MessageBroker. + * @param leadership_algorithm The concrete class to be used as leadership + * broker. * @param messaging_backend The concrete class to be used as message broker. */ - DistributedAlgorithmNode( - const string &node_id, - LeadershipBrokerType leadership_algorithm, - MessageBrokerType messaging_backend - ); + DistributedAlgorithmNode(const string& node_id, + LeadershipBrokerType leadership_algorithm, + MessageBrokerType messaging_backend); // -------------------------------------------------------------------------------------------- // Public API @@ -87,9 +90,11 @@ class DistributedAlgorithmNode : public MessageFactory { bool is_leader(); /** - * Returns the id of the network leader, or "" if no leader is known by this node. + * Returns the id of the network leader, or "" if no leader is known by this + * node. * - * @return The id of the network leader, or "" if no leader is known by this node. + * @return The id of the network leader, or "" if no leader is known by this + * node. */ string leader_id(); @@ -103,12 +108,12 @@ class DistributedAlgorithmNode : public MessageFactory { /** * Adds a node in the list of known peers. * - * Note that this methods DOESN'T add the passed peer into the network. The peer is - * supposed to be already in the network. + * Note that this methods DOESN'T add the passed peer into the network. The + * peer is supposed to be already in the network. * * @param peer_id The ID of the node being added as a peer. */ - void add_peer(const string &peer_id); + void add_peer(const string& peer_id); /** * Returns this node's ID. @@ -120,24 +125,25 @@ class DistributedAlgorithmNode : public MessageFactory { /** * Broadcasts a command to all nodes in the network. * - * All nodes in the network will be reached (not only the known peers) and the command - * will be executed. + * All nodes in the network will be reached (not only the known peers) and the + * command will be executed. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. */ - void broadcast(const string &command, const vector &args); + void broadcast(const string& command, const vector& args); /** * Sends a command to the passed node. * - * The target node is supposed to be a known peer. If not, an exception is thrown. + * The target node is supposed to be a known peer. If not, an exception is + * thrown. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. * @recipient The target node for the command. */ - void send(const string &command, const vector &args, const string &recipient); + void send(const string& command, const vector& args, const string& recipient); /** * Build the Message object which is supposed to execute the passed command. @@ -146,7 +152,7 @@ class DistributedAlgorithmNode : public MessageFactory { * @param args Arguments for the command. * @return A Message object */ - virtual shared_ptr message_factory(string &command, vector &args); + virtual shared_ptr message_factory(string& command, vector& args); /** * Gracefully shuts down threads or any other resources being used. @@ -159,23 +165,24 @@ class DistributedAlgorithmNode : public MessageFactory { /** * This method is called whenever a new node joins the network. * - * Every node that joins the network will broadcast a Message to everyone already joined. - * However, it's up to each node to decide whether or not the newly joined node will be added - * as a known peer. + * Every node that joins the network will broadcast a Message to everyone + * already joined. However, it's up to each node to decide whether or not the + * newly joined node will be added as a known peer. * * @param node_id The ID of the newly joined node. */ - virtual void node_joined_network(const string &node_id) = 0; + virtual void node_joined_network(const string& node_id) = 0; /** - * Casts a vote (which is the ID of the node being voted) in a leadership election. + * Casts a vote (which is the ID of the node being voted) in a leadership + * election. * - * @return This node's vote (which is the ID of the node being voted) for leader. + * @return This node's vote (which is the ID of the node being voted) for + * leader. */ virtual string cast_leadership_vote() = 0; -private: - + private: struct { string NODE_JOINED_NETWORK = "node_joined_network"; } known_commands; @@ -185,6 +192,6 @@ class DistributedAlgorithmNode : public MessageFactory { shared_ptr message_broker; }; -} // namespace distributed_algorithm_node +} // namespace distributed_algorithm_node -#endif // _DISTRIBUTED_ALGORITHM_NODE_DISTRIBUTEDALGORITHMNODE_H +#endif // _DISTRIBUTED_ALGORITHM_NODE_DISTRIBUTEDALGORITHMNODE_H diff --git a/src/distributed_algorithm_node/LeadershipBroker.cc b/src/distributed_algorithm_node/LeadershipBroker.cc index ec48b27..e0a1783 100644 --- a/src/distributed_algorithm_node/LeadershipBroker.cc +++ b/src/distributed_algorithm_node/LeadershipBroker.cc @@ -1,4 +1,5 @@ #include "LeadershipBroker.h" + #include "Utils.h" using namespace distributed_algorithm_node; @@ -6,16 +7,13 @@ using namespace distributed_algorithm_node; // ------------------------------------------------------------------------------------------------- // Constructors and destructors -LeadershipBroker::LeadershipBroker() { - this->network_leader_id = ""; -} +LeadershipBroker::LeadershipBroker() { this->network_leader_id = ""; } -LeadershipBroker::~LeadershipBroker() { -} +LeadershipBroker::~LeadershipBroker() {} shared_ptr LeadershipBroker::factory(LeadershipBrokerType instance_type) { switch (instance_type) { - case LeadershipBrokerType::SINGLE_MASTER_SERVER : { + case LeadershipBrokerType::SINGLE_MASTER_SERVER: { return shared_ptr(new SingleMasterServer()); } default: { @@ -25,34 +23,24 @@ shared_ptr LeadershipBroker::factory(LeadershipBrokerType inst } } -SingleMasterServer::SingleMasterServer() { -} +SingleMasterServer::SingleMasterServer() {} + +SingleMasterServer::~SingleMasterServer() {} -SingleMasterServer::~SingleMasterServer() { -} - // ------------------------------------------------------------------------------------------------- // Public superclass API -string LeadershipBroker::leader_id() { - return this->network_leader_id; -} +string LeadershipBroker::leader_id() { return this->network_leader_id; } -void LeadershipBroker::set_leader_id(const string &leader_id) { - this->network_leader_id = leader_id; -} +void LeadershipBroker::set_leader_id(const string& leader_id) { this->network_leader_id = leader_id; } -bool LeadershipBroker::has_leader() { - return (this->network_leader_id != ""); -} +bool LeadershipBroker::has_leader() { return (this->network_leader_id != ""); } void LeadershipBroker::set_message_broker(shared_ptr message_broker) { this->message_broker = message_broker; } - + // ------------------------------------------------------------------------------------------------- // Concrete implementation of abstract LeadershipBroker API -void SingleMasterServer::start_leader_election(const string &my_vote) { - this->set_leader_id(my_vote); -} +void SingleMasterServer::start_leader_election(const string& my_vote) { this->set_leader_id(my_vote); } diff --git a/src/distributed_algorithm_node/LeadershipBroker.h b/src/distributed_algorithm_node/LeadershipBroker.h index 54df65c..d908889 100644 --- a/src/distributed_algorithm_node/LeadershipBroker.h +++ b/src/distributed_algorithm_node/LeadershipBroker.h @@ -7,10 +7,7 @@ using namespace std; namespace distributed_algorithm_node { -enum class LeadershipBrokerType { - SINGLE_MASTER_SERVER -}; - +enum class LeadershipBrokerType { SINGLE_MASTER_SERVER }; // ------------------------------------------------------------------------------------------------- // Abstract superclass @@ -18,18 +15,17 @@ enum class LeadershipBrokerType { /** * Implements the algorithm for leader election. * - * This is the abstract class defining the API used by DistributedAlgorithmNodes to deal with leader election. - * Users of the DistributedAlgorithmNode module aren't supposed to interact with LeadershipBroker directly. + * This is the abstract class defining the API used by DistributedAlgorithmNodes + * to deal with leader election. Users of the DistributedAlgorithmNode module + * aren't supposed to interact with LeadershipBroker directly. */ class LeadershipBroker { - -public: - + public: /** * Factory method for concrete subclasses. * - * @param instance_type Defines which subclass should be used to instantiate the - * LeadershipBroker. + * @param instance_type Defines which subclass should be used to instantiate + * the LeadershipBroker. * @return An instance of the selected LeadershipBroker subclass. */ static shared_ptr factory(LeadershipBrokerType instance_type); @@ -47,7 +43,8 @@ class LeadershipBroker { /** * Sets MessageBroker to be used to communicate with peers. * - * @param message_broker The MessageBroker to be used to ciommunicate with peers. + * @param message_broker The MessageBroker to be used to ciommunicate with + * peers. */ void set_message_broker(shared_ptr message_broker); @@ -63,7 +60,7 @@ class LeadershipBroker { * * @param leader_id The leader node ID. */ - void set_leader_id(const string &leader_id); + void set_leader_id(const string& leader_id); /** * Return true iff a leader has been defined. @@ -76,13 +73,12 @@ class LeadershipBroker { /** * Starts an election to define the leader of the network. * - * @param my_vote The vote casted by the hosting node to tghe leadership election. + * @param my_vote The vote casted by the hosting node to tghe leadership + * election. */ - virtual void start_leader_election(const string &my_vote) = 0; - - -private: + virtual void start_leader_election(const string& my_vote) = 0; + private: shared_ptr message_broker; string network_leader_id; }; @@ -91,14 +87,12 @@ class LeadershipBroker { // Concrete subclasses /** - * Concrete implementation of a leadership selection algorithm based in a topology of one server - * connected to N clients, where clients only know about the server which is always the leader of - * the network. + * Concrete implementation of a leadership selection algorithm based in a + * topology of one server connected to N clients, where clients only know about + * the server which is always the leader of the network. */ class SingleMasterServer : public LeadershipBroker { - -public: - + public: /** * Basic constructor */ @@ -109,14 +103,12 @@ class SingleMasterServer : public LeadershipBroker { */ ~SingleMasterServer(); - // ---------------------------------------------------------------- // Public LeadershipBroker abstract API - void start_leader_election(const string &my_vote); + void start_leader_election(const string& my_vote); }; -} // namespace distributed_algorithm_node - -#endif // _DISTRIBUTED_ALGORITHM_NODE_LEADERSHIPBROKER_H +} // namespace distributed_algorithm_node +#endif // _DISTRIBUTED_ALGORITHM_NODE_LEADERSHIPBROKER_H diff --git a/src/distributed_algorithm_node/Message.cc b/src/distributed_algorithm_node/Message.cc index 10a1eb6..8a0436c 100644 --- a/src/distributed_algorithm_node/Message.cc +++ b/src/distributed_algorithm_node/Message.cc @@ -1,23 +1,19 @@ #include "Message.h" + #include "DistributedAlgorithmNode.h" using namespace distributed_algorithm_node; -Message::Message() { -} +Message::Message() {} -Message::~Message() { -} +Message::~Message() {} // ------------------------------------------------------------------------------------------------- // Specialized Message subclasses -NodeJoinedNetwork::~NodeJoinedNetwork() { -} +NodeJoinedNetwork::~NodeJoinedNetwork() {} -NodeJoinedNetwork::NodeJoinedNetwork(string &node_id) { - this->joining_node = node_id; -} +NodeJoinedNetwork::NodeJoinedNetwork(string& node_id) { this->joining_node = node_id; } void NodeJoinedNetwork::act(shared_ptr node) { auto distributed_algorithm_node = dynamic_pointer_cast(node); diff --git a/src/distributed_algorithm_node/Message.h b/src/distributed_algorithm_node/Message.h index 1b82651..48c7668 100644 --- a/src/distributed_algorithm_node/Message.h +++ b/src/distributed_algorithm_node/Message.h @@ -1,9 +1,9 @@ #ifndef _DISTRIBUTED_ALGORITHM_NODE_MESSAGE_H #define _DISTRIBUTED_ALGORITHM_NODE_MESSAGE_H +#include #include #include -#include using namespace std; @@ -13,13 +13,12 @@ class DistributedAlgorithmNode; class Message; /** - * Interface to be implemented by nodes (concrete implementations of DistributedAlgorithmNode) in order to - * provide a factory method for the types of messages defined in its specific network. + * Interface to be implemented by nodes (concrete implementations of + * DistributedAlgorithmNode) in order to provide a factory method for the types + * of messages defined in its specific network. */ class MessageFactory { - -public: - + public: /** * Message factory method. * @@ -27,7 +26,7 @@ class MessageFactory { * @param args Arguments for the command. * @return An object of the proper class to deal with the passed command. */ - virtual shared_ptr message_factory(string &command, vector &args) = 0; + virtual shared_ptr message_factory(string& command, vector& args) = 0; }; // ------------------------------------------------------------------------------------------------- @@ -36,24 +35,23 @@ class MessageFactory { /** * Basic abstract class for Messages to be exchanged among nodes in the network. * - * Concrete subclasses should implement the act() method to perform whatever operation is - * required in the recipient node. + * Concrete subclasses should implement the act() method to perform whatever + * operation is required in the recipient node. * - * Note that Message objects don't actually get serialized and sent through the network. - * What's actually sent is some identifier that makes possible for the recipients to - * know which concrete class of Message should be instantiated there. + * Note that Message objects don't actually get serialized and sent through the + * network. What's actually sent is some identifier that makes possible for the + * recipients to know which concrete class of Message should be instantiated + * there. * - * Once the recipient receives this identifier, it instantiates an object of the proper - * class (a concrete implementation of Message) and executed act(), passing the target - * node as parameter. + * Once the recipient receives this identifier, it instantiates an object of the + * proper class (a concrete implementation of Message) and executed act(), + * passing the target node as parameter. */ class Message { - -public: - + public: /** - * Executes the action defined in the Message in the recipient node, which is passed as - * parameter. + * Executes the action defined in the Message in the recipient node, which is + * passed as parameter. * * @param node The DistributedAlgorithmNode which received the Message. */ @@ -69,32 +67,28 @@ class Message { */ ~Message(); -private: - + private: }; // ------------------------------------------------------------------------------------------------- // Concrete Messages used in basic DistributedAlgorithmNode settings /** - * Concrete Message implementation to deal with command "node_join_network", used - * by DistributedAlgorithmNode to notify other nodes in the network of the presence of a newly - * joined node. + * Concrete Message implementation to deal with command "node_join_network", + * used by DistributedAlgorithmNode to notify other nodes in the network of the + * presence of a newly joined node. */ class NodeJoinedNetwork : public Message { - -private: - + private: string joining_node; -public: - + public: /** * Basic constructor. * * @param node_id ID of the newly joined node. */ - NodeJoinedNetwork(string &node_id); + NodeJoinedNetwork(string& node_id); /** * Destructor. @@ -107,6 +101,6 @@ class NodeJoinedNetwork : public Message { void act(shared_ptr node); }; -} // namespace distributed_algorithm_node +} // namespace distributed_algorithm_node -#endif // _DISTRIBUTED_ALGORITHM_NODE_MESSAGE_H +#endif // _DISTRIBUTED_ALGORITHM_NODE_MESSAGE_H diff --git a/src/distributed_algorithm_node/MessageBroker.cc b/src/distributed_algorithm_node/MessageBroker.cc index 5a146f2..90a5e84 100644 --- a/src/distributed_algorithm_node/MessageBroker.cc +++ b/src/distributed_algorithm_node/MessageBroker.cc @@ -1,55 +1,52 @@ -#include -#include -#include #include #include #include +#include +#include +#include #include - #include "common.pb.h" -// TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node +// TODO: Once das-proto is updated, update atom_space_node to +// distributed_algorithm_node // #include "distributed_algorithm_node.grpc.pb.h" // #include "distributed_algorithm_node.pb.h" +#include "MessageBroker.h" +#include "Utils.h" #include "atom_space_node.grpc.pb.h" #include "atom_space_node.pb.h" -#include "Utils.h" -#include "MessageBroker.h" - using namespace distributed_algorithm_node; unsigned int SynchronousGRPC::MESSAGE_THREAD_COUNT = 10; unsigned int SynchronousSharedRAM::MESSAGE_THREAD_COUNT = 1; -unordered_map SynchronousSharedRAM::NODE_QUEUE; +unordered_map SynchronousSharedRAM::NODE_QUEUE; mutex SynchronousSharedRAM::NODE_QUEUE_MUTEX; // ------------------------------------------------------------------------------------------------- // Constructors and destructors -shared_ptr MessageBroker::factory( - MessageBrokerType instance_type, - shared_ptr host_node, - const string &node_id) { - +shared_ptr MessageBroker::factory(MessageBrokerType instance_type, + shared_ptr host_node, + const string& node_id) { switch (instance_type) { - case MessageBrokerType::RAM : { + case MessageBrokerType::RAM: { return shared_ptr(new SynchronousSharedRAM(host_node, node_id)); } - case MessageBrokerType::GRPC : { + case MessageBrokerType::GRPC: { return shared_ptr(new SynchronousGRPC(host_node, node_id)); } default: { Utils::error("Invalid MessageBrokerType: " + to_string((int) instance_type)); - return shared_ptr{}; // to avoid warnings + return shared_ptr{}; // to avoid warnings } } } -MessageBroker::MessageBroker(shared_ptr host_node, const string &node_id) { - if (! host_node) { +MessageBroker::MessageBroker(shared_ptr host_node, const string& node_id) { + if (!host_node) { Utils::error("Invalid NULL host_node"); } this->host_node = host_node; @@ -58,17 +55,14 @@ MessageBroker::MessageBroker(shared_ptr host_node, const string this->joined_network = false; } -MessageBroker::~MessageBroker() { -} +MessageBroker::~MessageBroker() {} -SynchronousSharedRAM::SynchronousSharedRAM( - shared_ptr host_node, - const string &node_id) : MessageBroker(host_node, node_id) { -} +SynchronousSharedRAM::SynchronousSharedRAM(shared_ptr host_node, const string& node_id) + : MessageBroker(host_node, node_id) {} SynchronousSharedRAM::~SynchronousSharedRAM() { if (this->joined_network) { - for (auto thread: inbox_threads) { + for (auto thread : inbox_threads) { thread->join(); } NODE_QUEUE_MUTEX.lock(); @@ -82,16 +76,15 @@ SynchronousSharedRAM::~SynchronousSharedRAM() { } } -SynchronousGRPC::SynchronousGRPC( - shared_ptr host_node, - const string &node_id) : MessageBroker(host_node, node_id) { +SynchronousGRPC::SynchronousGRPC(shared_ptr host_node, const string& node_id) + : MessageBroker(host_node, node_id) { this->grpc_server_started_flag = false; this->inbox_setup_finished_flag = false; } SynchronousGRPC::~SynchronousGRPC() { if (this->joined_network) { - for (auto thread: inbox_threads) { + for (auto thread : inbox_threads) { thread->join(); } this->grpc_server->Shutdown(); @@ -116,28 +109,28 @@ void SynchronousGRPC::grpc_thread_method() { void SynchronousSharedRAM::inbox_thread_method() { bool stop_flag = false; do { - void *request = this->incoming_messages.dequeue(); + void* request = this->incoming_messages.dequeue(); if (request != NULL) { - CommandLinePackage *message_data = (CommandLinePackage *) request; + CommandLinePackage* message_data = (CommandLinePackage*) request; if (message_data->is_broadcast) { if (message_data->visited.find(this->node_id) != message_data->visited.end()) { continue; } this->peers_mutex.lock(); - for (auto target: this->peers) { + for (auto target : this->peers) { if (message_data->visited.find(target) == message_data->visited.end()) { - CommandLinePackage *command_line = new CommandLinePackage( - message_data->command, - message_data->args); + CommandLinePackage* command_line = + new CommandLinePackage(message_data->command, message_data->args); command_line->is_broadcast = true; command_line->visited = message_data->visited; command_line->visited.insert(this->node_id); - NODE_QUEUE[target]->enqueue((void *) command_line); + NODE_QUEUE[target]->enqueue((void*) command_line); } } this->peers_mutex.unlock(); } - std::shared_ptr message = this->host_node->message_factory(message_data->command, message_data->args); + std::shared_ptr message = + this->host_node->message_factory(message_data->command, message_data->args); if (message) { message->act(this->host_node); delete message_data; @@ -152,16 +145,16 @@ void SynchronousSharedRAM::inbox_thread_method() { Utils::sleep(); } } - } while (! stop_flag); + } while (!stop_flag); } void SynchronousGRPC::inbox_thread_method() { bool stop_flag = false; set_inbox_setup_finished(); do { - void *request = this->incoming_messages.dequeue(); + void* request = this->incoming_messages.dequeue(); if (request != NULL) { - dasproto::MessageData *message_data = (dasproto::MessageData *) request; + dasproto::MessageData* message_data = (dasproto::MessageData*) request; if (message_data->is_broadcast()) { this->peers_mutex.lock(); unsigned int num_peers = this->peers.size(); @@ -180,11 +173,14 @@ void SynchronousGRPC::inbox_thread_method() { } message_data->add_visited_recipients(this->node_id); this->peers_mutex.lock(); - for (auto target: this->peers) { + for (auto target : this->peers) { if (visited.find(target) == visited.end()) { - // TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node - // auto stub = dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(target, grpc::InsecureChannelCredentials())); - auto stub = dasproto::AtomSpaceNode::NewStub(grpc::CreateChannel(target, grpc::InsecureChannelCredentials())); + // TODO: Once das-proto is updated, update atom_space_node to + // distributed_algorithm_node auto stub = + // dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(target, + // grpc::InsecureChannelCredentials())); + auto stub = dasproto::AtomSpaceNode::NewStub( + grpc::CreateChannel(target, grpc::InsecureChannelCredentials())); stub->execute_message(&(context[cursor]), *message_data, &(reply[cursor])); cursor++; } @@ -212,19 +208,19 @@ void SynchronousGRPC::inbox_thread_method() { Utils::sleep(); } } - } while (! stop_flag); + } while (!stop_flag); } // ------------------------------------------------------------------------------------------------- // MessageBroker API -void MessageBroker::add_peer(const string &peer_id) { +void MessageBroker::add_peer(const string& peer_id) { peers_mutex.lock(); peers.insert(peer_id); peers_mutex.unlock(); } -bool MessageBroker::is_peer(const string &peer_id) { +bool MessageBroker::is_peer(const string& peer_id) { bool answer = true; this->peers_mutex.lock(); if (peers.find(peer_id) == peers.end()) { @@ -261,41 +257,37 @@ void SynchronousSharedRAM::join_network() { NODE_QUEUE_MUTEX.unlock(); } for (unsigned int i = 0; i < MESSAGE_THREAD_COUNT; i++) { - this->inbox_threads.push_back(new thread( - &SynchronousSharedRAM::inbox_thread_method, - this)); + this->inbox_threads.push_back(new thread(&SynchronousSharedRAM::inbox_thread_method, this)); } this->joined_network = true; } -void SynchronousSharedRAM::send( - const string &command, - const vector &args, - const string &recipient) { - - if (! this->is_shutting_down()) { - if (! is_peer(recipient)) { +void SynchronousSharedRAM::send(const string& command, + const vector& args, + const string& recipient) { + if (!this->is_shutting_down()) { + if (!is_peer(recipient)) { Utils::error("Unknown peer: " + recipient); } - CommandLinePackage *command_line = new CommandLinePackage(command, args); - NODE_QUEUE[recipient]->enqueue((void *) command_line); + CommandLinePackage* command_line = new CommandLinePackage(command, args); + NODE_QUEUE[recipient]->enqueue((void*) command_line); } } -void SynchronousSharedRAM::broadcast(const string &command, const vector &args) { - if (! this->is_shutting_down()) { +void SynchronousSharedRAM::broadcast(const string& command, const vector& args) { + if (!this->is_shutting_down()) { this->peers_mutex.lock(); unsigned int num_peers = this->peers.size(); if (num_peers == 0) { this->peers_mutex.unlock(); return; } - CommandLinePackage *command_line; - for (auto peer_id: this->peers) { + CommandLinePackage* command_line; + for (auto peer_id : this->peers) { command_line = new CommandLinePackage(command, args); command_line->is_broadcast = true; command_line->visited.insert(this->node_id); - NODE_QUEUE[peer_id]->enqueue((void *) command_line); + NODE_QUEUE[peer_id]->enqueue((void*) command_line); } this->peers_mutex.unlock(); } @@ -305,50 +297,43 @@ void SynchronousSharedRAM::broadcast(const string &command, const vector // SynchronousGRPC void SynchronousGRPC::join_network() { - this->grpc_thread = new std::thread( - &SynchronousGRPC::grpc_thread_method, - this); - while (! this->grpc_server_started()) { + this->grpc_thread = new std::thread(&SynchronousGRPC::grpc_thread_method, this); + while (!this->grpc_server_started()) { Utils::sleep(); } for (unsigned int i = 0; i < MESSAGE_THREAD_COUNT; i++) { - this->inbox_threads.push_back(new thread( - &SynchronousGRPC::inbox_thread_method, - this)); + this->inbox_threads.push_back(new thread(&SynchronousGRPC::inbox_thread_method, this)); } - while (! this->inbox_setup_finished()) { + while (!this->inbox_setup_finished()) { Utils::sleep(); } } -void SynchronousGRPC::add_peer(const string &peer_id) { - MessageBroker::add_peer(peer_id); -} - -void SynchronousGRPC::send( - const string &command, - const vector &args, - const string &recipient) { +void SynchronousGRPC::add_peer(const string& peer_id) { MessageBroker::add_peer(peer_id); } - if (! is_peer(recipient)) { +void SynchronousGRPC::send(const string& command, const vector& args, const string& recipient) { + if (!is_peer(recipient)) { Utils::error("Unknown peer: " + recipient); } dasproto::MessageData message_data; message_data.set_command(command); - for (auto arg: args) { + for (auto arg : args) { message_data.add_args(arg); } message_data.set_sender(this->node_id); message_data.set_is_broadcast(false); dasproto::Empty reply; grpc::ClientContext context; - // TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node - // auto stub = dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(recipient, grpc::InsecureChannelCredentials())); - auto stub = dasproto::AtomSpaceNode::NewStub(grpc::CreateChannel(recipient, grpc::InsecureChannelCredentials())); + // TODO: Once das-proto is updated, update atom_space_node to + // distributed_algorithm_node auto stub = + // dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(recipient, + // grpc::InsecureChannelCredentials())); + auto stub = dasproto::AtomSpaceNode::NewStub( + grpc::CreateChannel(recipient, grpc::InsecureChannelCredentials())); stub->execute_message(&context, message_data, &reply); } -void SynchronousGRPC::broadcast(const string &command, const vector &args) { +void SynchronousGRPC::broadcast(const string& command, const vector& args) { this->peers_mutex.lock(); unsigned int num_peers = this->peers.size(); if (num_peers == 0) { @@ -358,18 +343,21 @@ void SynchronousGRPC::broadcast(const string &command, const vector &arg dasproto::Empty reply[num_peers]; grpc::ClientContext context[num_peers]; unsigned int cursor = 0; - for (auto peer_id: this->peers) { + for (auto peer_id : this->peers) { dasproto::MessageData message_data; message_data.set_command(command); - for (auto arg: args) { + for (auto arg : args) { message_data.add_args(arg); } message_data.set_sender(this->node_id); message_data.set_is_broadcast(true); message_data.add_visited_recipients(this->node_id); - // TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node - // auto stub = dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(peer_id, grpc::InsecureChannelCredentials())); - auto stub = dasproto::AtomSpaceNode::NewStub(grpc::CreateChannel(peer_id, grpc::InsecureChannelCredentials())); + // TODO: Once das-proto is updated, update atom_space_node to + // distributed_algorithm_node auto stub = + // dasproto::DistributedAlgorithmNode::NewStub(grpc::CreateChannel(peer_id, + // grpc::InsecureChannelCredentials())); + auto stub = dasproto::AtomSpaceNode::NewStub( + grpc::CreateChannel(peer_id, grpc::InsecureChannelCredentials())); stub->execute_message(&(context[cursor]), message_data, &(reply[cursor])); cursor++; } @@ -411,27 +399,23 @@ bool SynchronousGRPC::inbox_setup_finished() { // ------------------------------------------------------------------------------------------------- // GRPC Server API -grpc::Status SynchronousGRPC::ping( - grpc::ServerContext* grpc_context, - const dasproto::Empty* request, - dasproto::Ack* reply) { - +grpc::Status SynchronousGRPC::ping(grpc::ServerContext* grpc_context, + const dasproto::Empty* request, + dasproto::Ack* reply) { reply->set_msg("PING"); - if (! this->is_shutting_down()) { + if (!this->is_shutting_down()) { return grpc::Status::OK; } else { return grpc::Status::CANCELLED; } } -grpc::Status SynchronousGRPC::execute_message( - grpc::ServerContext* grpc_context, - const dasproto::MessageData* request, - dasproto::Empty* reply) { - - if (! this->is_shutting_down()) { +grpc::Status SynchronousGRPC::execute_message(grpc::ServerContext* grpc_context, + const dasproto::MessageData* request, + dasproto::Empty* reply) { + if (!this->is_shutting_down()) { // TODO: fix memory leak - this->incoming_messages.enqueue((void *) new dasproto::MessageData(*request)); + this->incoming_messages.enqueue((void*) new dasproto::MessageData(*request)); return grpc::Status::OK; } else { return grpc::Status::CANCELLED; @@ -441,11 +425,10 @@ grpc::Status SynchronousGRPC::execute_message( // ------------------------------------------------------------------------------------------------- // Common utility classes -CommandLinePackage::CommandLinePackage(const string &command, const vector &args) { +CommandLinePackage::CommandLinePackage(const string& command, const vector& args) { this->command = command; this->args = args; this->is_broadcast = false; } -CommandLinePackage::~CommandLinePackage() { -} +CommandLinePackage::~CommandLinePackage() {} diff --git a/src/distributed_algorithm_node/MessageBroker.h b/src/distributed_algorithm_node/MessageBroker.h index 3c78cbc..2ee6814 100644 --- a/src/distributed_algorithm_node/MessageBroker.h +++ b/src/distributed_algorithm_node/MessageBroker.h @@ -1,13 +1,14 @@ #ifndef _DISTRIBUTED_ALGORITHM_NODE_MESSAGEBROKER_H #define _DISTRIBUTED_ALGORITHM_NODE_MESSAGEBROKER_H -#include -#include +#include #include #include -#include +#include +#include -// TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node +// TODO: Once das-proto is updated, update atom_space_node to +// distributed_algorithm_node #include "atom_space_node.grpc.pb.h" // #include "distributed_algorithm_node.grpc.pb.h" @@ -20,10 +21,7 @@ using namespace commons; namespace distributed_algorithm_node { -enum class MessageBrokerType { - RAM, - GRPC -}; +enum class MessageBrokerType { RAM, GRPC }; class DistributedAlgorithmNode; @@ -33,35 +31,36 @@ class DistributedAlgorithmNode; /** * Implements the communication layer used by nodes to exchange Messages. * - * This is the abstract class defining the API used by DistributedAlgorithmNodes to exchange messages. - * Users of the DistributedAlgorithmNode module aren't supposed to interact with MessageBroker directly. + * This is the abstract class defining the API used by DistributedAlgorithmNodes + * to exchange messages. Users of the DistributedAlgorithmNode module aren't + * supposed to interact with MessageBroker directly. */ class MessageBroker { - -public: - + public: /** * Factory method for concrete subclasses. * - * @param instance_type Defines which subclass should be used to instantiate the MessageBroker - * @param host_node The object responsible for building Message objects. Typically, it's The - * node this MessageBroker belongs to. - * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker belongs to. + * @param instance_type Defines which subclass should be used to instantiate + * the MessageBroker + * @param host_node The object responsible for building Message objects. + * Typically, it's The node this MessageBroker belongs to. + * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker + * belongs to. * @return An instance of the selected MessageBroker subclass. */ - static shared_ptr factory( - MessageBrokerType instance_type, - shared_ptr host_node, - const string &node_id); + static shared_ptr factory(MessageBrokerType instance_type, + shared_ptr host_node, + const string& node_id); /** * Basic constructor * - * @param host_node The object responsible for building Message objects. Typically, it's The - * node this MessageBroker belongs to. - * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker belongs to. + * @param host_node The object responsible for building Message objects. + * Typically, it's The node this MessageBroker belongs to. + * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker + * belongs to. */ - MessageBroker(shared_ptr host_node, const string &node_id); + MessageBroker(shared_ptr host_node, const string& node_id); /** * Destructor. @@ -76,7 +75,7 @@ class MessageBroker { * * @param peer_id The ID of the newly known peer. */ - virtual void add_peer(const string &peer_id); + virtual void add_peer(const string& peer_id); /** * Returns true iff the passed peer has been previously added @@ -84,18 +83,20 @@ class MessageBroker { * @param peer_id Peer id being checked. * @return true iff the passed peer has been previously added */ - bool is_peer(const string &peer_id); + bool is_peer(const string& peer_id); /** - * Gracefully shuts down threads or any other resources being used in communication. + * Gracefully shuts down threads or any other resources being used in + * communication. */ void graceful_shutdown(); /** * Returns true iff this MessageBroker is shuting down. * - * The idea is to allow concrete subclasses to know when a graceful shutdown has been requested - * so threads or any other resources being used in communication can be stoped/released/etc. + * The idea is to allow concrete subclasses to know when a graceful shutdown + * has been requested so threads or any other resources being used in + * communication can be stoped/released/etc. */ bool is_shutting_down(); @@ -110,27 +111,25 @@ class MessageBroker { /** * Broadcasts a command to all nodes in the network. * - * All nodes in the network will be reached (not only the known peers) and the command - * will be executed. + * All nodes in the network will be reached (not only the known peers) and the + * command will be executed. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. */ - virtual void broadcast(const string &command, const vector &args) = 0; + virtual void broadcast(const string& command, const vector& args) = 0; /** * Sends a command to the passed node. * - * The target node is supposed to be a known peer. If not, an exception is thrown. + * The target node is supposed to be a known peer. If not, an exception is + * thrown. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. * @recipient The target node for the command. */ - virtual void send( - const string &command, - const vector &args, - const string &recipient) = 0; + virtual void send(const string& command, const vector& args, const string& recipient) = 0; shared_ptr host_node; unordered_set peers; @@ -145,22 +144,20 @@ class MessageBroker { // Concrete subclasses /** - * Concrete implementation of MessageBroker using shared queues in RAM to exchange Message among - * nodes. + * Concrete implementation of MessageBroker using shared queues in RAM to + * exchange Message among nodes. * * Nodes are supposed to be running in the same runtime process. */ class SynchronousSharedRAM : public MessageBroker { - -public: - + public: /** * Basic constructor * - * @param host_node The object responsible for building Message objects. Typically, it's The - * node this MessageBroker belongs to. + * @param host_node The object responsible for building Message objects. + * Typically, it's The node this MessageBroker belongs to. */ - SynchronousSharedRAM(shared_ptr host_node, const string &node_id); + SynchronousSharedRAM(shared_ptr host_node, const string& node_id); /** * Destructor. @@ -180,52 +177,54 @@ class SynchronousSharedRAM : public MessageBroker { /** * Broadcasts a command to all nodes in the network. * - * All nodes in the network will be reached (not only the known peers) and the command - * will be executed. Basically the Message is sent to all known peers which, in their turns, - * re-send it to their known peers until there's no other peer to spread it. The GRPC object - * used to send the request contains a list of visited nodes so a request is never re-sent - * to nodes that have already received it. + * All nodes in the network will be reached (not only the known peers) and the + * command will be executed. Basically the Message is sent to all known peers + * which, in their turns, re-send it to their known peers until there's no + * other peer to spread it. The GRPC object used to send the request contains + * a list of visited nodes so a request is never re-sent to nodes that have + * already received it. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. */ - virtual void broadcast(const string &command, const vector &args); + virtual void broadcast(const string& command, const vector& args); /** * Sends a command to the passed node. * - * The target node is supposed to be a known peer. If not, an exception is thrown. - * Uses the client GRPC channel to send the command to the target. + * The target node is supposed to be a known peer. If not, an exception is + * thrown. Uses the client GRPC channel to send the command to the target. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. * @recipient The target node for the command. */ - virtual void send(const string &command, const vector &args, const string &recipient); - -private: + virtual void send(const string& command, const vector& args, const string& recipient); + private: static unsigned int MESSAGE_THREAD_COUNT; - static unordered_map NODE_QUEUE; + static unordered_map NODE_QUEUE; static mutex NODE_QUEUE_MUTEX; - vector inbox_threads; - SharedQueue incoming_messages; // Thread safe container + vector inbox_threads; + SharedQueue incoming_messages; // Thread safe container // Methods used to start threads void inbox_thread_method(); }; /** - * Concrete implementation of MessageBroker using GRPC to exchange Message among nodes. + * Concrete implementation of MessageBroker using GRPC to exchange Message among + * nodes. * - * Synchronous GRPS calls are used to send commands between nodes in the network. When joining - * the network, each node initializes a request queue and a thread to listen to a PORT for - * GRPC calls (this thread is what GRPC's documentation calls a GRPC Server). This way this node - * becomes capable of answering GRPC requests. + * Synchronous GRPS calls are used to send commands between nodes in the + * network. When joining the network, each node initializes a request queue and + * a thread to listen to a PORT for GRPC calls (this thread is what GRPC's + * documentation calls a GRPC Server). This way this node becomes capable of + * answering GRPC requests. * - * In addition to this, another queue is initialized for outgoing Messages and another thread is - * started to observe this queue. + * In addition to this, another queue is initialized for outgoing Messages and + * another thread is started to observe this queue. * * A Client GRPC channel is created for each the newly inserted peer. * @@ -235,37 +234,38 @@ class SynchronousSharedRAM : public MessageBroker { * - A GRPC thread listening for the rpc command requests * - N threads reading from this queue and processing the requested commands. * - An outgoing queue with waiting-to-be-sent outgoing commands - * - N threads observing the outgoing queue and processing this queue to send requests to other - * nodes. + * - N threads observing the outgoing queue and processing this queue to send + * requests to other nodes. * - * When one of the methods to send messages is called (e.g. broadcast() or send()), the passed - * command is enqueued in the outgoing queue and the methoid returns immetialely, meaning that that - * is no guarantee that the Message have been received by the other node(s) when the method returns. - * A thread will dequeue the request and use a previously created client GRPC channel to make the - * GRPC rpc call, sending the command to the target node. + * When one of the methods to send messages is called (e.g. broadcast() or + * send()), the passed command is enqueued in the outgoing queue and the methoid + * returns immetialely, meaning that that is no guarantee that the Message have + * been received by the other node(s) when the method returns. A thread will + * dequeue the request and use a previously created client GRPC channel to make + * the GRPC rpc call, sending the command to the target node. * - * In the target node, the GRPC server thread will get the requested command and enequeue it in the - * incomming queue. Then a thread will dequeue this request and execute the requested command on - * the target node. + * In the target node, the GRPC server thread will get the requested command and + * enequeue it in the incomming queue. Then a thread will dequeue this request + * and execute the requested command on the target node. * - * No rpc answer is used in these GRPC calls. So if a command expects an answer to return, this - * answer is supposed to be implemented as a separate Message going back from the target node to - * the node that originated the request. + * No rpc answer is used in these GRPC calls. So if a command expects an answer + * to return, this answer is supposed to be implemented as a separate Message + * going back from the target node to the node that originated the request. */ -// TODO: Once das-proto is updated, update atom_space_node to distributed_algorithm_node -// class SynchronousGRPC : public MessageBroker, public dasproto::DistributedAlgorithmNode::Service { +// TODO: Once das-proto is updated, update atom_space_node to +// distributed_algorithm_node class SynchronousGRPC : public MessageBroker, +// public dasproto::DistributedAlgorithmNode::Service { class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Service { - -public: - + public: /** * Basic constructor * - * @param host_node The object responsible for building Message objects. Typically, it's The - * node this MessageBroker belongs to. - * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker belongs to. + * @param host_node The object responsible for building Message objects. + * Typically, it's The node this MessageBroker belongs to. + * @param node_id The ID of the DistributedAlgorithmNode this MessageBroker + * belongs to. */ - SynchronousGRPC(shared_ptr host_node, const string &node_id); + SynchronousGRPC(shared_ptr host_node, const string& node_id); /** * Destructor. @@ -273,13 +273,13 @@ class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Se ~SynchronousGRPC(); /** - * Adds additional processing to superclass' add_peer() basically only adds the new peer id - * into a container. Here, a GRPC channel is created and stored in the object for further use - * when sending Messages. + * Adds additional processing to superclass' add_peer() basically only adds + * the new peer id into a container. Here, a GRPC channel is created and + * stored in the object for further use when sending Messages. * * @param peer_id The ID of the newly known peer. */ - virtual void add_peer(const string &peer_id); + virtual void add_peer(const string& peer_id); // ---------------------------------------------------------------- // Public MessageBroker abstract API @@ -287,36 +287,38 @@ class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Se /** * Inserts the host node into the network. * - * Initialize incoming and outgoing queues and starts threads to process each of them. - * Also initializes the GRPC Server thread to listen to the GRPC calls. + * Initialize incoming and outgoing queues and starts threads to process each + * of them. Also initializes the GRPC Server thread to listen to the GRPC + * calls. */ virtual void join_network(); /** * Broadcasts a command to all nodes in the network. * - * All nodes in the network will be reached (not only the known peers) and the command - * will be executed. Basically the Message is sent to all known peers which, in their turns, - * re-send it to their known peers until there's no other peer to spread it. The GRPC object - * used to send the request contains a list of visited nodes so a request is never re-sent - * to nodes that have already received it. + * All nodes in the network will be reached (not only the known peers) and the + * command will be executed. Basically the Message is sent to all known peers + * which, in their turns, re-send it to their known peers until there's no + * other peer to spread it. The GRPC object used to send the request contains + * a list of visited nodes so a request is never re-sent to nodes that have + * already received it. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. */ - virtual void broadcast(const string &command, const vector &args); + virtual void broadcast(const string& command, const vector& args); /** * Sends a command to the passed node. * - * The target node is supposed to be a known peer. If not, an exception is thrown. - * Uses the client GRPC channel to send the command to the target. + * The target node is supposed to be a known peer. If not, an exception is + * thrown. Uses the client GRPC channel to send the command to the target. * * @param command The command to be executed in the target nodes. * @param args Arguments for the command. * @recipient The target node for the command. */ - virtual void send(const string &command, const vector &args, const string &recipient); + virtual void send(const string& command, const vector& args, const string& recipient); // ---------------------------------------------------------------- // Public GRPC API @@ -326,27 +328,24 @@ class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Se * * This is a standard rpc in DAS proto which all servers implement. */ - grpc::Status ping( - grpc::ServerContext* grpc_context, - const dasproto::Empty* request, - dasproto::Ack* reply) override; + grpc::Status ping(grpc::ServerContext* grpc_context, + const dasproto::Empty* request, + dasproto::Ack* reply) override; /** * Delivers a Message to be remotely executed. */ - grpc::Status execute_message( - grpc::ServerContext* grpc_context, - const dasproto::MessageData* request, - dasproto::Empty* reply) override; - -private: + grpc::Status execute_message(grpc::ServerContext* grpc_context, + const dasproto::MessageData* request, + dasproto::Empty* reply) override; + private: static unsigned int MESSAGE_THREAD_COUNT; unique_ptr grpc_server; - thread *grpc_thread; - vector inbox_threads; - SharedQueue incoming_messages; // Thread safe container - SharedQueue outgoing_messages; // Thread safe container + thread* grpc_thread; + vector inbox_threads; + SharedQueue incoming_messages; // Thread safe container + SharedQueue outgoing_messages; // Thread safe container bool grpc_server_started_flag; mutex grpc_server_started_flag_mutex; @@ -366,16 +365,15 @@ class SynchronousGRPC : public MessageBroker, public dasproto::AtomSpaceNode::Se // Common utility classes class CommandLinePackage { - public: - CommandLinePackage(const string &command, const vector &args); - ~CommandLinePackage(); - string command; - vector args; - bool is_broadcast; - unordered_set visited; + public: + CommandLinePackage(const string& command, const vector& args); + ~CommandLinePackage(); + string command; + vector args; + bool is_broadcast; + unordered_set visited; }; -} // namespace distributed_algorithm_node - -#endif // _DISTRIBUTED_ALGORITHM_NODE_MESSAGEBROKER_H +} // namespace distributed_algorithm_node +#endif // _DISTRIBUTED_ALGORITHM_NODE_MESSAGEBROKER_H diff --git a/src/docker/Dockerfile b/src/docker/Dockerfile index 6a72193..f6ea434 100644 --- a/src/docker/Dockerfile +++ b/src/docker/Dockerfile @@ -20,7 +20,7 @@ RUN mkdir -p \ RUN yes | apt update -y \ && yes | apt install -y git build-essential curl protobuf-compiler python3 python3-pip cmake \ - libevent-dev libssl-dev pkg-config \ + libevent-dev libssl-dev pkg-config libncurses5\ && yes | apt clean -y \ && rm -rf /var/lib/apt/lists/* diff --git a/src/hasher/expression_hasher.cc b/src/hasher/expression_hasher.cc index 53f331e..3287c37 100644 --- a/src/hasher/expression_hasher.cc +++ b/src/hasher/expression_hasher.cc @@ -1,14 +1,16 @@ -#include +#include "expression_hasher.h" + #include +#include #include + #include "mbedtls/md5.h" -#include "expression_hasher.h" static unsigned char MD5_BUFFER[16]; static char HASH[HANDLE_HASH_SIZE]; static char HASHABLE_STRING[MAX_HASHABLE_STRING_SIZE]; -char *compute_hash(char *input) { +char* compute_hash(char* input) { mbedtls_md5_context context; mbedtls_md5_init(&context); mbedtls_md5_starts(&context); @@ -16,17 +18,15 @@ char *compute_hash(char *input) { mbedtls_md5_finish(&context, MD5_BUFFER); mbedtls_md5_free(&context); for (unsigned int i = 0; i < 16; i++) { - sprintf((char *) ((unsigned long) HASH + 2 * i), "%02x", MD5_BUFFER[i]); + sprintf((char*) ((unsigned long) HASH + 2 * i), "%02x", MD5_BUFFER[i]); } HASH[32] = '\0'; return strdup(HASH); } -char *named_type_hash(char *name) { - return compute_hash(name); -} +char* named_type_hash(char* name) { return compute_hash(name); } -char *terminal_hash(char *type, char *name) { +char* terminal_hash(char* type, char* name) { if (strlen(type) + strlen(name) >= MAX_HASHABLE_STRING_SIZE) { fprintf(stderr, "Invalid (too large) terminal name"); exit(1); @@ -35,8 +35,7 @@ char *terminal_hash(char *type, char *name) { return compute_hash(HASHABLE_STRING); } -char *composite_hash(char **elements, unsigned int nelements) { - +char* composite_hash(char** elements, unsigned int nelements) { unsigned int total_size = 0; unsigned int element_size[nelements]; @@ -57,9 +56,9 @@ char *composite_hash(char **elements, unsigned int nelements) { unsigned long cursor = 0; for (unsigned int i = 0; i < nelements; i++) { if (i == (nelements - 1)) { - strcpy((char *) (HASHABLE_STRING + cursor), elements[i]); + strcpy((char*) (HASHABLE_STRING + cursor), elements[i]); } else { - sprintf((char *) (HASHABLE_STRING + cursor), "%s%c", elements[i], JOINING_CHAR); + sprintf((char*) (HASHABLE_STRING + cursor), "%s%c", elements[i], JOINING_CHAR); cursor += 1; } cursor += element_size[i]; @@ -68,8 +67,8 @@ char *composite_hash(char **elements, unsigned int nelements) { return compute_hash(HASHABLE_STRING); } -char *expression_hash(char *type_hash, char **elements, unsigned int nelements) { - char *composite[nelements + 1]; +char* expression_hash(char* type_hash, char** elements, unsigned int nelements) { + char* composite[nelements + 1]; composite[0] = type_hash; for (unsigned int i = 0; i < nelements; i++) { composite[i + 1] = elements[i]; diff --git a/src/hasher/expression_hasher.h b/src/hasher/expression_hasher.h index 78d309f..7f795d9 100644 --- a/src/hasher/expression_hasher.h +++ b/src/hasher/expression_hasher.h @@ -1,15 +1,15 @@ #ifndef EXPRESSIONHASHER_H #define EXPRESSIONHASHER_H -#define JOINING_CHAR ((char ) ' ') +#define JOINING_CHAR ((char) ' ') #define MAX_LITERAL_OR_SYMBOL_SIZE ((size_t) 10000) #define MAX_HASHABLE_STRING_SIZE ((size_t) 100000) #define HANDLE_HASH_SIZE ((unsigned int) 33) -char *compute_hash(char *input); -char *named_type_hash(char *name); -char *terminal_hash(char *type, char *name); -char *expression_hash(char *type_hash, char **elements, unsigned int nelements); -char *composite_hash(char **elements, unsigned int nelements); +char* compute_hash(char* input); +char* named_type_hash(char* name); +char* terminal_hash(char* type, char* name); +char* expression_hash(char* type_hash, char** elements, unsigned int nelements); +char* composite_hash(char** elements, unsigned int nelements); #endif diff --git a/src/hyperon_das_atomdb_cpp/atom_db_publicist.h b/src/hyperon_das_atomdb_cpp/atom_db_publicist.h index b2de6eb..12e899e 100644 --- a/src/hyperon_das_atomdb_cpp/atom_db_publicist.h +++ b/src/hyperon_das_atomdb_cpp/atom_db_publicist.h @@ -6,15 +6,17 @@ using namespace atomdb; /** * @class AtomDBPublicist - * @brief A publicist class for AtomDB that exposes certain protected member functions. + * @brief A publicist class for AtomDB that exposes certain protected member + * functions. * - * This class inherits from AtomDB and makes the following protected member functions - * accessible publicly: + * This class inherits from AtomDB and makes the following protected member + * functions accessible publicly: * - _build_link * - _build_node * - _get_atom * - * This can be useful for testing or other purposes where access to these functions is required. + * This can be useful for testing or other purposes where access to these + * functions is required. */ class AtomDBPublicist : public AtomDB { public: diff --git a/src/hyperon_das_atomdb_cpp/bind_helpers.h b/src/hyperon_das_atomdb_cpp/bind_helpers.h index 04161e3..9195e0c 100644 --- a/src/hyperon_das_atomdb_cpp/bind_helpers.h +++ b/src/hyperon_das_atomdb_cpp/bind_helpers.h @@ -1,23 +1,27 @@ /** * @file bind_helpers.h - * @brief This header file contains helper functions and type definitions for binding C++ - * classes and structures to Python using the `nanobind` library. The primary purpose - * of these helpers is to facilitate the conversion of C++ objects to Python objects - * and vice versa, enabling seamless interoperability between the two languages. + * @brief This header file contains helper functions and type definitions for + * binding C++ classes and structures to Python using the `nanobind` library. + * The primary purpose of these helpers is to facilitate the conversion of C++ + * objects to Python objects and vice versa, enabling seamless interoperability + * between the two languages. * * The file includes: * - Type definitions for tuples representing various C++ structures. - * - Functions for converting between C++ and Python representations of these structures. - * - Functions for converting composite types between C++ lists and Python lists. + * - Functions for converting between C++ and Python representations of these + * structures. + * - Functions for converting composite types between C++ lists and Python + * lists. * - Functions for converting C++ objects to Python dictionaries. - * - Functions for initializing and updating C++ objects from Python representations. + * - Functions for initializing and updating C++ objects from Python + * representations. */ #pragma once #include #include -#include #include +#include using namespace std; using namespace atomdb; @@ -54,7 +58,8 @@ using LinkTuple = // Tuple for Link /** * @brief Converts a composite type list to a Python list. * @param ct_list The composite type list to be converted. - * @return A Python list (`nb::list`) containing the elements of the composite type list. + * @return A Python list (`nb::list`) containing the elements of the composite + * type list. */ static nb::list composite_type_to_pylist(const ListOfAny& ct_list) { nb::list py_list; @@ -73,7 +78,8 @@ static nb::list composite_type_to_pylist(const ListOfAny& ct_list) { /** * @brief Converts a Python list to a composite type list. * @param py_list The Python list to be converted. - * @return A composite type list (`ListOfAny`) containing the elements of the Python list. + * @return A composite type list (`ListOfAny`) containing the elements of the + * Python list. */ static ListOfAny pylist_to_composite_type(const nb::list& py_list) { ListOfAny ct_list; @@ -95,7 +101,8 @@ static ListOfAny pylist_to_composite_type(const nb::list& py_list) { /** * @brief Converts an Atom object to a Python dictionary. * @param self The Atom object to be converted. - * @return A Python dictionary (`nb::dict`) containing the attributes of the Atom. + * @return A Python dictionary (`nb::dict`) containing the attributes of the + * Atom. */ static nb::dict atom_to_dict(const Atom& self) { nb::dict dict; @@ -110,7 +117,8 @@ static nb::dict atom_to_dict(const Atom& self) { /** * @brief Converts a Node object to a Python dictionary. * @param self The Node object to be converted. - * @return A Python dictionary (`nb::dict`) containing the attributes of the Node. + * @return A Python dictionary (`nb::dict`) containing the attributes of the + * Node. */ static nb::dict node_to_dict(const Node& self) { nb::dict dict = atom_to_dict(self); @@ -121,7 +129,8 @@ static nb::dict node_to_dict(const Node& self) { /** * @brief Converts a Link object to a Python dictionary. * @param self The Link object to be converted. - * @return A Python dictionary (`nb::dict`) containing the attributes of the Link. + * @return A Python dictionary (`nb::dict`) containing the attributes of the + * Link. */ static nb::dict link_to_dict(const Link& self) { nb::dict dict = atom_to_dict(self); diff --git a/src/hyperon_das_atomdb_cpp/hyperon_das_atomdb_cpp_bind.cc b/src/hyperon_das_atomdb_cpp/hyperon_das_atomdb_cpp_bind.cc index 01ac0e4..e98ce6c 100644 --- a/src/hyperon_das_atomdb_cpp/hyperon_das_atomdb_cpp_bind.cc +++ b/src/hyperon_das_atomdb_cpp/hyperon_das_atomdb_cpp_bind.cc @@ -30,7 +30,8 @@ using namespace nb::literals; NB_MODULE(ext, m) { // --------------------------------------------------------------------------------------------- - // constants submodule ------------------------------------------------------------------------- + // constants submodule + // ------------------------------------------------------------------------- nb::module_ constants = m.def_submodule("constants"); constants.attr("WILDCARD") = WILDCARD; constants.attr("WILDCARD_HASH") = WILDCARD_HASH; @@ -55,7 +56,8 @@ NB_MODULE(ext, m) { .def_ro_static("TARGETS_DOCUMENTS", &FieldNames::TARGETS_DOCUMENTS) .def_ro_static("CUSTOM_ATTRIBUTES", &FieldNames::CUSTOM_ATTRIBUTES); // --------------------------------------------------------------------------------------------- - // database submodule -------------------------------------------------------------------------- + // database submodule + // -------------------------------------------------------------------------- nb::module_ database = m.def_submodule("database"); nb::class_(database, "AtomDB") .def(nb::init<>()) @@ -264,14 +266,16 @@ NB_MODULE(ext, m) { .def("_build_link", &AtomDBPublicist::_build_link, "link_params"_a, "is_toplevel"_a = true) .def("_get_atom", &AtomDBPublicist::_get_atom, "handle"_a); // --------------------------------------------------------------------------------------------- - // adapters submodule -------------------------------------------------------------------------- + // adapters submodule + // -------------------------------------------------------------------------- nb::module_ adapters = m.def_submodule("adapters"); nb::class_(adapters, "InMemoryDB") .def(nb::init(), "database_name"_a = "das") .def("__repr__", [](const InMemoryDB& self) -> string { return ""; }) .def("__str__", [](const InMemoryDB& self) -> string { return ""; }); // --------------------------------------------------------------------------------------------- - // exceptions submodule ------------------------------------------------------------------------ + // exceptions submodule + // ------------------------------------------------------------------------ nb::module_ exceptions = m.def_submodule("exceptions"); nb::exception(exceptions, "AtomDbBaseException"); nb::exception(exceptions, "AddLinkException"); @@ -281,7 +285,8 @@ NB_MODULE(ext, m) { nb::exception(exceptions, "InvalidOperationException"); nb::exception(exceptions, "RetryException"); // --------------------------------------------------------------------------------------------- - // document_types submodule -------------------------------------------------------------------- + // document_types submodule + // -------------------------------------------------------------------- nb::module_ document_types = m.def_submodule("document_types"); nb::class_(document_types, "Atom") .def_rw("_id", &Atom::_id) @@ -298,9 +303,9 @@ NB_MODULE(ext, m) { nb::class_(document_types, "Node") .def( /** - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Node objects, use the - * constructor with all parameters. + * @note This constructor is intended to be used only when passing in + * the basic building parameters to other functions. For creating + * complete new Node objects, use the constructor with all parameters. */ nb::init(document_types, "Link") .def( /** - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Link objects, use the - * constructor with all parameters. + * @note This constructor is intended to be used only when passing in + * the basic building parameters to other functions. For creating + * complete new Link objects, use the constructor with all parameters. */ nb::init AtomDB::_reformat_document(const shared_ptr AtomDB::_build_node(const Node& node_params) { diff --git a/src/hyperon_das_atomdb_cpp_lib/database.h b/src/hyperon_das_atomdb_cpp_lib/database.h index dbbba8e..29acc2c 100644 --- a/src/hyperon_das_atomdb_cpp_lib/database.h +++ b/src/hyperon_das_atomdb_cpp_lib/database.h @@ -2,10 +2,11 @@ * @file database.h * @brief Abstract base class for the AtomDB database interface. * - * This header file defines the AtomDB class, which serves as an abstract base class for - * interacting with the AtomDB database. The AtomDB class provides a comprehensive interface - * for querying, adding, and managing atoms, nodes, and links within the database. Derived - * classes must implement the pure virtual methods to provide concrete functionality. + * This header file defines the AtomDB class, which serves as an abstract base + * class for interacting with the AtomDB database. The AtomDB class provides a + * comprehensive interface for querying, adding, and managing atoms, nodes, and + * links within the database. Derived classes must implement the pure virtual + * methods to provide concrete functionality. * * The AtomDB interface supports various operations, including: * - Retrieving atoms by different criteria (e.g., field, index, text field). @@ -13,19 +14,20 @@ * - Reindexing the database and creating field indexes. * - Bulk inserting atoms and committing changes. * - * The class is designed to be extended by specific database implementations, allowing for - * flexible and customizable database interactions. It includes static methods for building - * node and link handles, as well as methods for checking the existence of nodes and links, - * retrieving atoms, and reformatting documents. + * The class is designed to be extended by specific database implementations, + * allowing for flexible and customizable database interactions. It includes + * static methods for building node and link handles, as well as methods for + * checking the existence of nodes and links, retrieving atoms, and reformatting + * documents. * - * The AtomDB class also defines several pure virtual methods that must be implemented by - * derived classes. These methods cover a wide range of database operations, such as - * retrieving node handles, querying the database by field or text, managing links, - * reindexing, and more. + * The AtomDB class also defines several pure virtual methods that must be + * implemented by derived classes. These methods cover a wide range of database + * operations, such as retrieving node handles, querying the database by field + * or text, managing links, reindexing, and more. * - * @note This class uses several custom types and utility classes, such as StringList, - * ExpressionHasher, NodeParams, LinkParams, and KwArgs, which are defined elsewhere - * in the project. + * @note This class uses several custom types and utility classes, such as + * StringList, ExpressionHasher, NodeParams, LinkParams, and KwArgs, which are + * defined elsewhere in the project. */ #pragma once @@ -41,11 +43,12 @@ using namespace std; namespace atomdb { /** - * @brief A Plain Old Data (POD) type representing various boolean flags for configuration options. + * @brief A Plain Old Data (POD) type representing various boolean flags for + * configuration options. * - * This structure contains several boolean flags that control different aspects of the - * configuration, such as target formatting, document handling, representation depth, - * and scope of operation. + * This structure contains several boolean flags that control different aspects + * of the configuration, such as target formatting, document handling, + * representation depth, and scope of operation. */ struct KwArgs { bool no_target_format = false; @@ -58,10 +61,10 @@ struct KwArgs { /** * @brief Abstract base class for the AtomDB database interface. * - * The AtomDB class defines the interface for interacting with the AtomDB database. - * It provides various pure virtual methods for querying, adding, and managing atoms, - * nodes, and links within the database. Derived classes must implement these methods - * to provide concrete functionality. + * The AtomDB class defines the interface for interacting with the AtomDB + * database. It provides various pure virtual methods for querying, adding, and + * managing atoms, nodes, and links within the database. Derived classes must + * implement these methods to provide concrete functionality. * * The AtomDB interface supports operations such as: * - Retrieving atoms by various criteria (e.g., field, index, text field). @@ -115,33 +118,38 @@ class AtomDB { * @brief Checks if a node with the specified type and name exists. * @param node_type A string representing the type of the node. * @param node_name A string representing the name of the node. - * @return A boolean value indicating whether the node exists (true) or not (false). + * @return A boolean value indicating whether the node exists (true) or not + * (false). */ bool node_exists(const string& node_type, const string& node_name) const; /** * @brief Checks if a link with the specified type and target handles exists. * @param link_type A string representing the type of the link. - * @param target_handles A vector of strings representing the handles of the link's targets. - * @return A boolean value indicating whether the link exists (true) or not (false). + * @param target_handles A vector of strings representing the handles of the + * link's targets. + * @return A boolean value indicating whether the link exists (true) or not + * (false). */ bool link_exists(const string& link_type, const StringList& target_handles) const; /** - * @brief Retrieves an atom from the database using its handle and optional params. + * @brief Retrieves an atom from the database using its handle and optional + * params. * @param handle A string representing the handle of the atom to be retrieved. - * @param kwargs An optional Kwargs object containing additional retrieval options, as follows: - * `no_target_format` (`bool`, optional): If True, return the document without - * transforming it to the target format. Defaults to False. - * `targets_document` (`bool`, optional): If True, include the `targets_document` - * in the response. Defaults to False. - * `deep_representation` (`bool`, optional): If True, include a deep - * representation of the targets. Defaults to False. + * @param kwargs An optional Kwargs object containing additional retrieval + * options, as follows: `no_target_format` (`bool`, optional): If True, return + * the document without transforming it to the target format. Defaults to + * False. `targets_document` (`bool`, optional): If True, include the + * `targets_document` in the response. Defaults to False. + * `deep_representation` (`bool`, optional): If True, include a + * deep representation of the targets. Defaults to False. * @return A const shared pointer to an Atom object. */ const shared_ptr get_atom(const string& handle, const KwArgs& kwargs = {}) const; - // PURE VIRTUAL PUBLIC METHODS ///////////////////////////////////////////////////////////////// + // PURE VIRTUAL PUBLIC METHODS + // ///////////////////////////////////////////////////////////////// /** * @brief Get the handle of the node with the specified type and name. @@ -166,7 +174,8 @@ class AtomDB { virtual const string get_node_type(const string& node_handle) const = 0; /** - * @brief Get the handles of (a) node(s) of the specified type containing the given substring. + * @brief Get the handles of (a) node(s) of the specified type containing the + * given substring. * @param node_type The node type. * @param substring The substring to search for in node names. * @return List of handles of nodes whose names matched the criteria. @@ -184,13 +193,16 @@ class AtomDB { /** * @brief Retrieves atoms from the database using the specified index. - * @param index_id The ID of the index to use for retrieving atoms from the database. + * @param index_id The ID of the index to use for retrieving atoms from the + * database. * @param query A vector of ordered maps representing the query parameters. - * @param cursor An integer representing the cursor position for pagination (default is 0). - * @param chunk_size An integer representing the number of atoms to retrieve in one chunk - * (default is 500). - * @return A pair containing an cursor and a list of atoms. The cursor is used for pagination - * or further retrieval operations, and the list contains the retrieved atoms. + * @param cursor An integer representing the cursor position for pagination + * (default is 0). + * @param chunk_size An integer representing the number of atoms to retrieve + * in one chunk (default is 500). + * @return A pair containing an cursor and a list of atoms. The cursor is used + * for pagination or further retrieval operations, and the list contains the + * retrieved atoms. */ virtual const pair get_atoms_by_index( const string& index_id, @@ -266,7 +278,8 @@ class AtomDB { /** * @brief Retrieves incoming link handles for the specified atom. * @param atom_handle A string representing the handle of the atom. - * @param kwargs An const reference to a Kwargs object containing additional retrieval options. + * @param kwargs An const reference to a Kwargs object containing additional + * retrieval options. * @return A list of strings representing the incoming link handles. */ virtual const StringList get_incoming_links_handles(const string& atom_handle, @@ -275,7 +288,8 @@ class AtomDB { /** * @brief Retrieves incoming link atoms for the specified atom. * @param atom_handle A string representing the handle of the atom. - * @param kwargs An const reference to a Kwargs object containing additional retrieval options. + * @param kwargs An const reference to a Kwargs object containing additional + * retrieval options. * @return A list of Atom objects representing the incoming links. */ virtual const vector> get_incoming_links_atoms( @@ -285,7 +299,8 @@ class AtomDB { * @brief Retrieves matched links of the specified type and target handles. * @param link_type A string representing the type of the links to retrieve. * @param target_handles A list of strings representing the target handles. - * @param kwargs An const reference to a Kwargs object containing additional retrieval options. + * @param kwargs An const reference to a Kwargs object containing additional + * retrieval options. * @return A set of handles that matched. */ virtual const StringUnorderedSet get_matched_links(const string& link_type, @@ -295,7 +310,8 @@ class AtomDB { /** * @brief Retrieves matched type templates based on the specified template. * @param _template A list of strings representing the template. - * @param kwargs An const reference to a Kwargs object containing additional retrieval options. + * @param kwargs An const reference to a Kwargs object containing additional + * retrieval options. * @return A set of handles that matched. */ virtual const StringUnorderedSet get_matched_type_template(const StringList& _template, @@ -304,7 +320,8 @@ class AtomDB { /** * @brief Retrieves matched types based on the specified link type. * @param link_type A string representing the type of the links to retrieve. - * @param kwargs A const reference to a Kwargs object containing additional retrieval options. + * @param kwargs A const reference to a Kwargs object containing additional + * retrieval options. * @return A set of handles that matched. */ virtual const StringUnorderedSet get_matched_type(const string& link_type, @@ -313,13 +330,15 @@ class AtomDB { /** * @brief Retrieves the type of the atom with the specified handle. * @param handle A string representing the handle of the atom. - * @return An optional string containing the type of the atom if found, otherwise nullopt. + * @return An optional string containing the type of the atom if found, + * otherwise nullopt. */ virtual const optional get_atom_type(const string& handle) const = 0; /** * @brief Count the total number of atoms in the database. - * @return A dictionary containing the count of node atoms, link atoms, and total atoms. + * @return A dictionary containing the count of node atoms, link atoms, and + * total atoms. */ virtual const unordered_map count_atoms() const = 0; @@ -330,37 +349,44 @@ class AtomDB { /** * @brief Adds a node to the database. - * @param node_params A NodeParams object containing the parameters for the node. + * @param node_params A NodeParams object containing the parameters for the + * node. * @return A const shared pointer to a Node object. */ virtual const shared_ptr add_node(const Node& node_params) = 0; /** * @brief Adds a link to the database. - * @param link_params A LinkParams object containing the parameters for the link. - * @param toplevel A boolean indicating whether the link is a top-level link (default is true). + * @param link_params A LinkParams object containing the parameters for the + * link. + * @param toplevel A boolean indicating whether the link is a top-level link + * (default is true). * @return A const shared pointer to a Link object. */ virtual const shared_ptr add_link(const Link& link_params, bool toplevel = true) = 0; /** - * @brief Reindexes the inverted pattern index according to the passed templates. + * @brief Reindexes the inverted pattern index according to the passed + * templates. * - * This function reindexes the inverted pattern index based on the specified pattern - * templates. The pattern templates are specified by atom type in a map, where each - * atom type maps to a pattern template. + * This function reindexes the inverted pattern index based on the specified + * pattern templates. The pattern templates are specified by atom type in a + * map, where each atom type maps to a pattern template. * - * @param pattern_index_templates A map where the keys are atom types and the values - * are pattern templates. Each pattern template is a vector of maps, where each - * map specifies a pattern template with: - * - "named_type": A boolean indicating whether the named type should be included. - * - "selected_positions": A vector of integers specifying the selected positions. + * @param pattern_index_templates A map where the keys are atom types and the + * values are pattern templates. Each pattern template is a vector of maps, + * where each map specifies a pattern template with: + * - "named_type": A boolean indicating whether the named type should + * be included. + * - "selected_positions": A vector of integers specifying the selected + * positions. * - * Pattern templates are applied to each link entered in the atom space to determine - * which entries should be created in the inverted pattern index. Entries in the inverted - * pattern index are like patterns where the link type and each of its targets may be - * replaced by wildcards. For instance, given a similarity link Similarity(handle1, handle2), - * it could be used to create any of the following entries in the inverted pattern index: + * Pattern templates are applied to each link entered in the atom space to + * determine which entries should be created in the inverted pattern index. + * Entries in the inverted pattern index are like patterns where the link type + * and each of its targets may be replaced by wildcards. For instance, given a + * similarity link Similarity(handle1, handle2), it could be used to create + * any of the following entries in the inverted pattern index: * * - *(handle1, handle2) * @@ -370,10 +396,10 @@ class AtomDB { * * - Similarity(*, *) * - * If we create all possibilities of index entries for all links, the pattern index size - * will grow exponentially, so we limit the entries we want to create by each type of link. - * This is what a pattern template for a given link type is. For instance, if we apply this - * pattern template: + * If we create all possibilities of index entries for all links, the pattern + * index size will grow exponentially, so we limit the entries we want to + * create by each type of link. This is what a pattern template for a given + * link type is. For instance, if we apply this pattern template: * * @code * `{ "named_type": false, "selected_positions": {0, 1} }` @@ -425,7 +451,8 @@ class AtomDB { /** * @brief Insert multiple documents into the database. - * @param documents A list of Atom objects, each representing a document to be inserted into the db. + * @param documents A list of Atom objects, each representing a document to be + * inserted into the db. */ virtual void bulk_insert(const vector>& documents) = 0; @@ -443,26 +470,32 @@ class AtomDB { /** * @brief Reformats a document based on the provided params. * @param document A shared pointer to the Atom object to be reformatted. - * @param kwargs A const reference to a Kwargs object containing the reformatting options. - * @return A shared pointer with a copy of the reference object but with the new format. + * @param kwargs A const reference to a Kwargs object containing the + * reformatting options. + * @return A shared pointer with a copy of the reference object but with the + * new format. */ const shared_ptr _reformat_document(const shared_ptr& document, const KwArgs& kwargs = {}) const; protected: - // PROTECTED METHODS /////////////////////////////////////////////////////////////////////////// + // PROTECTED METHODS + // /////////////////////////////////////////////////////////////////////////// /** * @brief Builds a node with the specified parameters. - * @param node_params A NodeParams object containing the parameters for the node. + * @param node_params A NodeParams object containing the parameters for the + * node. * @return A shared pointer to a Node object. */ shared_ptr _build_node(const Node& node_params); /** * @brief Builds a link with the specified parameters. - * @param link_params A LinkParams object containing the parameters for the link. - * @param is_toplevel A boolean indicating whether the link is a top-level link. + * @param link_params A LinkParams object containing the parameters for the + * link. + * @param is_toplevel A boolean indicating whether the link is a top-level + * link. * @return A shared pointer to a Link object. */ virtual shared_ptr _build_link(const Link& link_params, bool is_toplevel = true); @@ -470,7 +503,8 @@ class AtomDB { /** * @brief Retrieves an atom from the database using its handle. * @param handle A string representing the handle of the atom to be retrieved. - * @return A const shared pointer to the Atom object representing the retrieved atom. + * @return A const shared pointer to the Atom object representing the + * retrieved atom. */ virtual const shared_ptr _get_atom(const string& handle) const = 0; }; diff --git a/src/hyperon_das_atomdb_cpp_lib/document_types.h b/src/hyperon_das_atomdb_cpp_lib/document_types.h index c4cbbff..1e5feb5 100644 --- a/src/hyperon_das_atomdb_cpp_lib/document_types.h +++ b/src/hyperon_das_atomdb_cpp_lib/document_types.h @@ -1,17 +1,20 @@ /** * @file document_types.h - * @brief Defines various classes representing atomic entities and their relationships in the atom - * database. + * @brief Defines various classes representing atomic entities and their + * relationships in the atom database. * - * This header file contains the definitions of several classes that represent different types of - * atomic entities and their relationships within the atom database. The classes include: - * - CustomAttributes: A type alias for `std::unordered_map`. - * - Atom: Represents a basic atomic entity with attributes such as ID, handle, composite type hash, - * named type, and optional custom attributes. - * - Node: Represents a node in the atom database, extending the Atom class by adding a name - * attribute. - * - Link: Represents a link in the atom database, encapsulating a composite type, named type hash, - * and a list of target hashes. It supports nested composite types and validates their structure. + * This header file contains the definitions of several classes that represent + * different types of atomic entities and their relationships within the atom + * database. The classes include: + * - CustomAttributes: A type alias for `std::unordered_map`. + * - Atom: Represents a basic atomic entity with attributes such as ID, handle, + * composite type hash, named type, and optional custom attributes. + * - Node: Represents a node in the atom database, extending the Atom class by + * adding a name attribute. + * - Link: Represents a link in the atom database, encapsulating a composite + * type, named type hash, and a list of target hashes. It supports nested + * composite types and validates their structure. */ #pragma once @@ -78,10 +81,10 @@ static string custom_attributes_to_string(const CustomAttributes& custom_attribu * @class Atom * @brief Represents an atomic entity with various attributes. * - * The Atom class encapsulates the properties of an atomic entity, including its ID, handle, - * composite type hash, named type, and optional custom attributes. It provides constructors - * for initialization, comparison operators, and a method to convert the object to a string - * representation. + * The Atom class encapsulates the properties of an atomic entity, including its + * ID, handle, composite type hash, named type, and optional custom attributes. + * It provides constructors for initialization, comparison operators, and a + * method to convert the object to a string representation. */ class Atom { public: @@ -96,10 +99,11 @@ class Atom { /** * @brief Constructs an Atom with a named type and optional custom attributes. * @param named_type The named type of the Atom. - * @param custom_attributes Optional custom attributes for the Atom. Defaults to an empty map. - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Atom objects, use the - * constructor with all parameters. + * @param custom_attributes Optional custom attributes for the Atom. Defaults + * to an empty map. + * @note This constructor is intended to be used only when passing in the + * basic building parameters to other functions. For creating complete new + * Atom objects, use the constructor with all parameters. */ Atom(const string& named_type, const CustomAttributes& custom_attributes = CustomAttributes{}) : named_type(named_type), custom_attributes(custom_attributes) {} @@ -108,9 +112,11 @@ class Atom { * @brief Constructs an Atom object with the given parameters. * @param id The unique identifier for the atom. * @param handle The handle for the atom. - * @param composite_type_hash The hash representing the composite type of the atom. + * @param composite_type_hash The hash representing the composite type of the + * atom. * @param named_type The named type of the atom. - * @param custom_attributes Optional custom attributes for the atom. Defaults to an empty map. + * @param custom_attributes Optional custom attributes for the atom. Defaults + * to an empty map. */ Atom(const string& id, const string& handle, @@ -146,8 +152,8 @@ class Atom { /** * @brief Converts the object to a string representation. - * @return A string representing the object, including its ID, handle, composite type hash, - * named type, and custom attributes. + * @return A string representing the object, including its ID, handle, + * composite type hash, named type, and custom attributes. */ virtual const string to_string() const noexcept { string result = "_id: '" + this->_id + "'"; @@ -164,8 +170,9 @@ class Atom { * @class Node * @brief Represents a node in the atom database, inheriting from Atom. * - * The Node class extends the Atom class by adding a name attribute. It includes constructors, - * equality operators, and a string representation method. The name attribute must not be empty. + * The Node class extends the Atom class by adding a name attribute. It includes + * constructors, equality operators, and a string representation method. The + * name attribute must not be empty. */ class Node : public Atom { public: @@ -177,10 +184,11 @@ class Node : public Atom { * @brief Constructs a Node with a type, name, and optional custom attributes. * @param type The type of the Node. * @param name The name of the Node. - * @param custom_attributes Optional custom attributes for the Node. Defaults to an empty map. - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Node objects, use the - * constructor with all parameters. + * @param custom_attributes Optional custom attributes for the Node. Defaults + * to an empty map. + * @note This constructor is intended to be used only when passing in the + * basic building parameters to other functions. For creating complete new + * Node objects, use the constructor with all parameters. * * Usage: * ``` @@ -190,12 +198,14 @@ class Node : public Atom { * Node( * "Concept", // type * "human", // name - * { {"weight": 0.8}, {"immutable": false} } // custom_attributes (optional) + * { {"weight": 0.8}, {"immutable": false} } // custom_attributes + * (optional) * ) * ); * * bool node2_is_immutable = ( - * get_custom_attribute(node2->custom_attributes, "immutable").value_or(false) + * get_custom_attribute(node2->custom_attributes, + * "immutable").value_or(false) * ); * cout << node2_is_immutable << endl; * // Output: @@ -203,9 +213,10 @@ class Node : public Atom { * * cout << node2.to_string() << endl; * // Output: - * Node(_id: 'af12f10f9ae2002a1607ba0b47ba8407', handle: 'af12f10f9ae2002a1607ba0b47ba8407', - * composite_type_hash: 'd99a604c79ce3c2e76a2f43488d5d4c3', named_type: 'Concept', custom_attributes: - * {immutable: false, weight: 0.800000}, name: 'human') + * Node(_id: 'af12f10f9ae2002a1607ba0b47ba8407', handle: + * 'af12f10f9ae2002a1607ba0b47ba8407', composite_type_hash: + * 'd99a604c79ce3c2e76a2f43488d5d4c3', named_type: 'Concept', + * custom_attributes: {immutable: false, weight: 0.800000}, name: 'human') * ``` */ Node(const string& type, @@ -220,7 +231,8 @@ class Node : public Atom { * @param composite_type_hash The hash representing the composite type. * @param named_type The named type of the Node. * @param name The name of the Node. - * @param custom_attributes Optional custom attributes for the Node. Defaults to an empty map. + * @param custom_attributes Optional custom attributes for the Node. Defaults + * to an empty map. */ Node(const string& id, const string& handle, @@ -256,18 +268,20 @@ class Node : public Atom { * @class Link * @brief Represents a link in the atom database, inheriting from Atom. * - * The Link class encapsulates a composite type, a named type hash, and a list of target hashes. - * It supports nested composite types and validates their structure. The class also provides - * functionality to compare links, convert them to string representations, and manage target - * documents. + * The Link class encapsulates a composite type, a named type hash, and a list + * of target hashes. It supports nested composite types and validates their + * structure. The class also provides functionality to compare links, convert + * them to string representations, and manage target documents. */ class Link : public Atom { public: using TargetsDocuments = vector>; /** - * `composite_type` is designed to hold a list of elements, where each element can either be a - * `string` (single hash) or another list of `strings`, allowing multiple levels of nesting. + * `composite_type` is designed to hold a list of elements, where each element + can either be a + * `string` (single hash) or another list of `strings`, allowing multiple + levels of nesting. * Example: ``` [ @@ -294,13 +308,15 @@ class Link : public Atom { Link() = default; /** - * @brief Constructs a Link with a type, targets documents, and optional custom attributes. + * @brief Constructs a Link with a type, targets documents, and optional + * custom attributes. * @param type The type of the Link. * @param targets The targets documents associated with the Link. - * @param custom_attributes Optional custom attributes for the Link. Defaults to an empty map. - * @note This constructor is intended to be used only when passing in the basic building - * parameters to other functions. For creating complete new Link objects, use the - * constructor with all parameters. + * @param custom_attributes Optional custom attributes for the Link. Defaults + * to an empty map. + * @note This constructor is intended to be used only when passing in the + * basic building parameters to other functions. For creating complete new + * Link objects, use the constructor with all parameters. * * Usage: * ``` @@ -308,24 +324,24 @@ class Link : public Atom { * auto link = db.add_link( * Link( * "Similarity", // type - * { // targets of Similarity link - * {Node("Concept", "monkey")}, // a node as a target of Similarity link - * {Node("Concept", "human")}, // another node as a target - * { // a link as a target of Similarity link - * Link("Dummicity", // type - * { // targets of Dummicity link - * {Node("Concept", "dummy1")}, - * {Node("Concept", "dummy2")} + * { // targets of + * Similarity link {Node("Concept", "monkey")}, // a node as a + * target of Similarity link {Node("Concept", "human")}, // + * another node as a target { // a + * link as a target of Similarity link Link("Dummicity", // type { // targets + * of Dummicity link {Node("Concept", "dummy1")}, {Node("Concept", "dummy2")} * } * ) * } * }, - * { {"weight": 0.8}, {"immutable": false} } // custom_attributes (optional) + * { {"weight": 0.8}, {"immutable": false} } // custom_attributes + * (optional) * ) * ); * * double link_weight = ( - * get_custom_attribute(link->custom_attributes, "weight").value_or(0.0) + * get_custom_attribute(link->custom_attributes, + * "weight").value_or(0.0) * ); * cout << link_weight << endl; * // Output: @@ -333,15 +349,17 @@ class Link : public Atom { * * cout << link.to_string() << endl; * // Output: - * Link(_id: '8ef9c2093150a022204fa6c9f0bc94f8', handle: '8ef9c2093150a022204fa6c9f0bc94f8', - * composite_type_hash: '8dd4c9ab591dbbd1e6eb511e71ef5aa9', named_type: 'Similarity', + * Link(_id: '8ef9c2093150a022204fa6c9f0bc94f8', handle: + * '8ef9c2093150a022204fa6c9f0bc94f8', composite_type_hash: + * '8dd4c9ab591dbbd1e6eb511e71ef5aa9', named_type: 'Similarity', * custom_attributes: {immutable: false, weight: 0.800000}, composite_type: * ['a9dea78180588431ec64d6bc4872fdbc', 'd99a604c79ce3c2e76a2f43488d5d4c3', * 'd99a604c79ce3c2e76a2f43488d5d4c3', ['44d25cf84a95f144d6e603ca28caadba', - * 'd99a604c79ce3c2e76a2f43488d5d4c3', 'd99a604c79ce3c2e76a2f43488d5d4c3']], named_type_hash: - * 'a9dea78180588431ec64d6bc4872fdbc', targets: ['1cdffc6b0b89ff41d68bec237481d1e1', - * 'af12f10f9ae2002a1607ba0b47ba8407', '087091095a266df1bfcc1ee01e79811c'], is_toplevel: true, - * targets_documents: []) + * 'd99a604c79ce3c2e76a2f43488d5d4c3', 'd99a604c79ce3c2e76a2f43488d5d4c3']], + * named_type_hash: 'a9dea78180588431ec64d6bc4872fdbc', targets: + * ['1cdffc6b0b89ff41d68bec237481d1e1', 'af12f10f9ae2002a1607ba0b47ba8407', + * '087091095a266df1bfcc1ee01e79811c'], is_toplevel: true, targets_documents: + * []) * ``` */ Link(const string& type, @@ -359,8 +377,10 @@ class Link : public Atom { * @param named_type_hash The hash of the named type. * @param targets The vector of target strings. * @param is_toplevel Boolean indicating if the link is top-level. - * @param custom_attributes Optional custom attributes. Defaults to an empty map. - * @param targets_documents Optional targets documents. Defaults to an empty vector. + * @param custom_attributes Optional custom attributes. Defaults to an empty + * map. + * @param targets_documents Optional targets documents. Defaults to an empty + * vector. */ Link(const string& id, const string& handle, @@ -390,7 +410,8 @@ class Link : public Atom { } if (not this->validate_composite_type(this->composite_type)) { throw invalid_argument( - "Invalid composite type. All elements must be strings or lists of strings."); + "Invalid composite type. All elements must be " + "strings or lists of strings."); } if (this->named_type_hash.empty()) { throw invalid_argument("Named type hash cannot be empty."); @@ -402,8 +423,8 @@ class Link : public Atom { /** * @brief Converts the Link object to a string representation. - * @return A string representing the Link object, including its composite type, named type hash, - * targets, top-level status, and target documents. + * @return A string representing the Link object, including its composite + * type, named type hash, targets, top-level status, and target documents. */ const string to_string() const noexcept override { string result = "Link(" + Atom::to_string(); @@ -463,13 +484,13 @@ class Link : public Atom { /** * @brief Validates the structure of a composite type. * - * This function checks whether the given composite type adheres to the expected structure. - * A composite type is a list where each element can be either a string or another list of - * the same type. The function ensures that all elements in the composite type meet these - * criteria. + * This function checks whether the given composite type adheres to the + * expected structure. A composite type is a list where each element can be + * either a string or another list of the same type. The function ensures that + * all elements in the composite type meet these criteria. * - * @param composite_type A list of elements of type std::any representing the composite type - * to be validated. + * @param composite_type A list of elements of type std::any representing the + * composite type to be validated. * @return true if the composite type is valid, false otherwise. */ static bool validate_composite_type(const ListOfAny& composite_type) { diff --git a/src/hyperon_das_atomdb_cpp_lib/exceptions.h b/src/hyperon_das_atomdb_cpp_lib/exceptions.h index 102d121..ee1110b 100644 --- a/src/hyperon_das_atomdb_cpp_lib/exceptions.h +++ b/src/hyperon_das_atomdb_cpp_lib/exceptions.h @@ -1,29 +1,34 @@ /** * @file exceptions.h - * @brief Defines custom exception classes for the Atom Database (atomdb) library. + * @brief Defines custom exception classes for the Atom Database (atomdb) + * library. * - * This header file contains the definitions of various exception classes used in the Atom - * Database (atomdb) library. These exceptions are designed to handle specific error conditions - * that may arise during the operation of the database. Each exception class inherits from - * AtomDbBaseException, which in turn inherits from the standard std::exception class. + * This header file contains the definitions of various exception classes used + * in the Atom Database (atomdb) library. These exceptions are designed to + * handle specific error conditions that may arise during the operation of the + * database. Each exception class inherits from AtomDbBaseException, which in + * turn inherits from the standard std::exception class. * - * The AtomDbBaseException class provides a mechanism to store and retrieve detailed error - * messages. It uses a static buffer (`what_buffer`) to ensure that the exception message remains - * valid and accessible even after the original C-string has been invalidated. This is - * particularly useful when interfacing with libraries like `nanobind` that may lazily access + * The AtomDbBaseException class provides a mechanism to store and retrieve + * detailed error messages. It uses a static buffer (`what_buffer`) to ensure + * that the exception message remains valid and accessible even after the + * original C-string has been invalidated. This is particularly useful when + * interfacing with libraries like `nanobind` that may lazily access * std::exception::what(). * * The following custom exception classes are defined: * - AtomDoesNotExist: Thrown when an atom does not exist in the database. * - AddNodeException: Thrown when adding a node to the database fails. * - AddLinkException: Thrown when adding a link to the database fails. - * - InvalidOperationException: Thrown when an invalid operation is performed on the database. + * - InvalidOperationException: Thrown when an invalid operation is performed on + * the database. * - RetryException: Raised for retryable errors. * - InvalidAtomDB: Raised for invalid Atom DB operations. * - * Each of these exception classes inherits from AtomDbBaseException and can be used to provide - * detailed error messages specific to the context in which the error occurred. + * Each of these exception classes inherits from AtomDbBaseException and can be + * used to provide detailed error messages specific to the context in which the + * error occurred. */ #pragma once @@ -38,11 +43,11 @@ namespace atomdb { /** * @brief Buffer to store the exception message. - * nanobind makes a lazy access to std::exception::what(), which can result in the - * underlying C-string being lost or invalidated. To work around this issue, we - * create a static buffer (what_buffer) to store the exception message. This ensures - * that the message remains valid and accessible even after the original C-string - * has been invalidated. + * nanobind makes a lazy access to std::exception::what(), which can result in + * the underlying C-string being lost or invalidated. To work around this issue, + * we create a static buffer (what_buffer) to store the exception message. This + * ensures that the message remains valid and accessible even after the original + * C-string has been invalidated. */ static char what_buffer[BUFFER_SIZE]; @@ -84,7 +89,8 @@ class AddLinkException : public AtomDbBaseException { }; /** - * @brief Exception thrown when an invalid operation is performed on the database. + * @brief Exception thrown when an invalid operation is performed on the + * database. */ class InvalidOperationException : public AtomDbBaseException { using AtomDbBaseException::AtomDbBaseException; diff --git a/src/hyperon_das_atomdb_cpp_lib/expression_hasher.h b/src/hyperon_das_atomdb_cpp_lib/expression_hasher.h index 123ca01..7167765 100644 --- a/src/hyperon_das_atomdb_cpp_lib/expression_hasher.h +++ b/src/hyperon_das_atomdb_cpp_lib/expression_hasher.h @@ -1,22 +1,25 @@ /** * @file expression_hasher.h - * @brief Header file for the ExpressionHasher class, providing utilities for generating MD5 hashes - * for various types of expressions. + * @brief Header file for the ExpressionHasher class, providing utilities for + * generating MD5 hashes for various types of expressions. * - * This file contains the definition of the ExpressionHasher class, which offers static methods to - * compute MD5 hashes for different types of expressions, including named types, terminal expressions, - * composite expressions, and general expressions. The class leverages the mbedtls library for MD5 - * hashing operations. + * This file contains the definition of the ExpressionHasher class, which offers + * static methods to compute MD5 hashes for different types of expressions, + * including named types, terminal expressions, composite expressions, and + * general expressions. The class leverages the mbedtls library for MD5 hashing + * operations. * - * The ExpressionHasher class is designed to handle strings and lists of strings as input for hashing. - * It ensures that the generated hashes are consistent and unique for different expressions, making it - * useful for scenarios where expression uniqueness and integrity are critical. + * The ExpressionHasher class is designed to handle strings and lists of strings + * as input for hashing. It ensures that the generated hashes are consistent and + * unique for different expressions, making it useful for scenarios where + * expression uniqueness and integrity are critical. * - * @note The class uses a maximum hashable string size of 100,000 characters and a joining character - * of a single space (' ') for concatenating elements before hashing. + * @note The class uses a maximum hashable string size of 100,000 characters and + * a joining character of a single space (' ') for concatenating elements before + * hashing. * - * @remark The class throws exceptions in cases where hashing operations fail or input constraints - * are violated, ensuring robust error handling. + * @remark The class throws exceptions in cases where hashing operations fail or + * input constraints are violated, ensuring robust error handling. * * Dependencies: * - mbedtls/md5.h: For MD5 hashing functions. @@ -38,17 +41,20 @@ namespace atomdb { /** * @class ExpressionHasher - * @brief A utility class for generating various types of hashes for expressions. + * @brief A utility class for generating various types of hashes for + * expressions. * - * The ExpressionHasher class provides static methods to compute MD5 hashes for different types of - * expressions, including named types, terminal expressions, composite expressions, and general - * expressions. It uses the mbedtls library for MD5 hashing. + * The ExpressionHasher class provides static methods to compute MD5 hashes for + * different types of expressions, including named types, terminal expressions, + * composite expressions, and general expressions. It uses the mbedtls library + * for MD5 hashing. * - * @note This class is designed to handle strings and lists of strings as input for hashing. + * @note This class is designed to handle strings and lists of strings as input + * for hashing. * - * @remark The class ensures that the generated hashes are consistent and unique for different - * expressions, making it useful for scenarios where expression uniqueness and integrity - * are critical. + * @remark The class ensures that the generated hashes are consistent and unique + * for different expressions, making it useful for scenarios where expression + * uniqueness and integrity are critical. */ class ExpressionHasher { public: @@ -81,7 +87,8 @@ class ExpressionHasher { /** * @brief Generates a hash for a composite expression. * - * @param elements A vector of strings representing the elements of the composite expression. + * @param elements A vector of strings representing the elements of the + * composite expression. * @return A string representing the hash of the composite expression. */ static const string composite_hash(const StringList& elements); @@ -93,7 +100,8 @@ class ExpressionHasher { * by applying additional hashing logic. * * @param hash_base A string representing the base hash. - * @return A string representing the composite hash generated from the base hash. + * @return A string representing the composite hash generated from the base + * hash. */ static const string composite_hash(const string& hash_base); @@ -101,7 +109,8 @@ class ExpressionHasher { * @brief Generates a hash for an expression. * * @param type_hash The hash of the type of the expression. - * @param elements A vector of strings representing the elements of the expression. + * @param elements A vector of strings representing the elements of the + * expression. * @return A string representing the hash of the expression. */ static const string expression_hash(const string& type_hash, const StringList& elements); diff --git a/src/hyperon_das_atomdb_cpp_lib/patterns.h b/src/hyperon_das_atomdb_cpp_lib/patterns.h index cb79995..4965fc4 100644 --- a/src/hyperon_das_atomdb_cpp_lib/patterns.h +++ b/src/hyperon_das_atomdb_cpp_lib/patterns.h @@ -1,15 +1,18 @@ /** * @file patterns.h - * @brief Utility functions for generating and manipulating binary matrices and pattern keys. + * @brief Utility functions for generating and manipulating binary matrices and + * pattern keys. * - * This header file contains utility functions for generating binary matrices, multiplying - * binary matrices by string matrices, and building pattern keys from a list of hash strings. - * These functions are part of the atomdb namespace and are used for various operations - * involving pattern generation and manipulation in the context of the das-atom-db project. + * This header file contains utility functions for generating binary matrices, + * multiplying binary matrices by string matrices, and building pattern keys + * from a list of hash strings. These functions are part of the atomdb namespace + * and are used for various operations involving pattern generation and + * manipulation in the context of the das-atom-db project. * * The main functionalities provided by this module include: * - Generating a binary matrix of a specified size. - * - Multiplying a binary matrix by a string matrix to produce a resulting matrix. + * - Multiplying a binary matrix by a string matrix to produce a resulting + * matrix. * - Building pattern keys using a list of hash strings. */ #pragma once @@ -47,7 +50,8 @@ unordered_map BINARY_MATRIX_CACHE = {{0, {{}}}}; * * @param numbers The size of the binary matrix to generate. * If numbers equal to 0, returns a matrix with an empty vector. - * @return A const reference to a binary matrix represented as a vector of vectors. + * @return A const reference to a binary matrix represented as a vector of + * vectors. */ const IntMatrix& generate_binary_matrix(size_t numbers) { if (BINARY_MATRIX_CACHE.find(numbers) == BINARY_MATRIX_CACHE.end()) { @@ -72,9 +76,11 @@ const IntMatrix& generate_binary_matrix(size_t numbers) { * * This function takes a binary matrix and a string matrix, and multiplies them * to produce a resulting matrix. Each element in the binary matrix determines - * whether to include the corresponding string from the string matrix or a wildcard. + * whether to include the corresponding string from the string matrix or a + * wildcard. * - * @param binary_matrix A binary matrix represented as a vector of vectors of integers. + * @param binary_matrix A binary matrix represented as a vector of vectors of + * integers. * @param string_matrix A vector of strings to multiply with the binary matrix. * @return A matrix represented as a vector of vectors of strings, where each * subvector is a row in the resulting matrix. @@ -103,7 +109,8 @@ StringMatrix multiply_binary_matrix_by_string_matrix(const IntMatrix& binary_mat * @brief Builds pattern keys using a list of hashes. * * This function takes a list of hash strings, generates a binary matrix, - * multiplies it by the hash list, and then generates pattern keys from the result. + * multiplies it by the hash list, and then generates pattern keys from the + * result. * * @param hash_list A vector of hash strings to build pattern keys from. * @return A vector of pattern keys generated from the hash list. diff --git a/src/hyperon_das_atomdb_cpp_lib/ram_only.cc b/src/hyperon_das_atomdb_cpp_lib/ram_only.cc index 5d8510a..c29a381 100644 --- a/src/hyperon_das_atomdb_cpp_lib/ram_only.cc +++ b/src/hyperon_das_atomdb_cpp_lib/ram_only.cc @@ -9,7 +9,8 @@ using namespace std; using namespace atomdb; -// PUBLIC METHODS ////////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS +// ////////////////////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------------ const string InMemoryDB::get_node_handle(const string& node_type, const string& node_name) const { @@ -356,7 +357,8 @@ void InMemoryDB::commit(const optional>& buffer) { throw runtime_error("Not implemented"); } -// PROTECTED OR PRIVATE METHODS //////////////////////////////////////////////////////////////////// +// PROTECTED OR PRIVATE METHODS +// //////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------------ const shared_ptr InMemoryDB::_get_atom(const string& handle) const { diff --git a/src/hyperon_das_atomdb_cpp_lib/ram_only.h b/src/hyperon_das_atomdb_cpp_lib/ram_only.h index 1b765a4..2c83285 100644 --- a/src/hyperon_das_atomdb_cpp_lib/ram_only.h +++ b/src/hyperon_das_atomdb_cpp_lib/ram_only.h @@ -1,23 +1,26 @@ /** * @file ram_only.h - * @brief Defines in-memory database classes for managing atoms, nodes, and links. + * @brief Defines in-memory database classes for managing atoms, nodes, and + * links. * - * This header file contains the definitions for the `Database` and `InMemoryDB` classes, - * which provide in-memory storage and management of various data types, including atoms, - * nodes, and links. These classes are designed to facilitate efficient in-memory operations - * without the overhead of persistent storage, making them suitable for applications that - * require fast data access and manipulation. + * This header file contains the definitions for the `Database` and `InMemoryDB` + * classes, which provide in-memory storage and management of various data + * types, including atoms, nodes, and links. These classes are designed to + * facilitate efficient in-memory operations without the overhead of persistent + * storage, making them suitable for applications that require fast data access + * and manipulation. * - * The `Database` class serves as a container for different types of data, using unordered - * maps to store atom types, nodes, links, and sets for managing relationships between them. - * It provides basic functionalities such as initialization and cleanup of the stored data. + * The `Database` class serves as a container for different types of data, using + * unordered maps to store atom types, nodes, links, and sets for managing + * relationships between them. It provides basic functionalities such as + * initialization and cleanup of the stored data. * - * The `InMemoryDB` class extends the `AtomDB` class and offers a comprehensive set of - * methods for adding, retrieving, and managing atoms, nodes, links, and their relationships. - * It includes functionalities for querying data, managing indexes, and handling complex - * data structures in memory. This class is intended for use in scenarios where data does - * not need to be persisted across sessions or can be reconstructed from other sources if - * needed. + * The `InMemoryDB` class extends the `AtomDB` class and offers a comprehensive + * set of methods for adding, retrieving, and managing atoms, nodes, links, and + * their relationships. It includes functionalities for querying data, managing + * indexes, and handling complex data structures in memory. This class is + * intended for use in scenarios where data does not need to be persisted across + * sessions or can be reconstructed from other sources if needed. * * Key functionalities provided by the `InMemoryDB` class include: * - Adding and retrieving nodes and links. @@ -28,9 +31,9 @@ * - Bulk insertion and retrieval of atoms. * - Committing changes to the database. * - * The classes in this module are designed to be flexible and efficient, providing a robust - * solution for managing in-memory data structures in applications that require high - * performance and low latency. + * The classes in this module are designed to be flexible and efficient, + * providing a robust solution for managing in-memory data structures in + * applications that require high performance and low latency. */ #pragma once @@ -43,7 +46,8 @@ using namespace std; namespace atomdb { /** - * @brief Represents an in-memory database for storing and managing atoms, nodes, and links. + * @brief Represents an in-memory database for storing and managing atoms, + * nodes, and links. */ class Database { public: @@ -67,26 +71,29 @@ class Database { }; /** - * @brief Represents an in-memory database for storing and managing atoms, nodes, and links. + * @brief Represents an in-memory database for storing and managing atoms, + * nodes, and links. * - * The InMemoryDB class inherits from the AtomDB class and provides an implementation for - * managing various types of data within an in-memory data structure. It supports operations - * such as adding, retrieving, and clearing atoms, nodes, links, and their relationships. + * The InMemoryDB class inherits from the AtomDB class and provides an + * implementation for managing various types of data within an in-memory data + * structure. It supports operations such as adding, retrieving, and clearing + * atoms, nodes, links, and their relationships. * - * This class uses unordered maps to store different types of data, including atom types, - * nodes, links, and sets for managing relationships between atoms. It is designed to be - * efficient for in-memory operations, making it suitable for applications that require - * fast access to data without the overhead of persistent storage. + * This class uses unordered maps to store different types of data, including + * atom types, nodes, links, and sets for managing relationships between atoms. + * It is designed to be efficient for in-memory operations, making it suitable + * for applications that require fast access to data without the overhead of + * persistent storage. * - * The InMemoryDB class is intended to be used in scenarios where data does not need to be - * persisted across sessions, or where the data can be reconstructed from other sources if - * needed. It provides a flexible and efficient way to manage complex data structures in - * memory. + * The InMemoryDB class is intended to be used in scenarios where data does not + * need to be persisted across sessions, or where the data can be reconstructed + * from other sources if needed. It provides a flexible and efficient way to + * manage complex data structures in memory. */ class InMemoryDB : public AtomDB { public: - InMemoryDB(const string& database_name = "das") : database_name(database_name) {}; - ~InMemoryDB() {}; + InMemoryDB(const string& database_name = "das") : database_name(database_name){}; + ~InMemoryDB(){}; const string get_node_handle(const string& node_type, const string& node_name) const override; @@ -191,8 +198,8 @@ class InMemoryDB : public AtomDB { * @brief Builds a hash for a named type template. * * This method takes a string representing a named type template and generates - * a hash for it. The hash can be used to uniquely identify the template within - * the database, ensuring efficient lookups and comparisons. + * a hash for it. The hash can be used to uniquely identify the template + * within the database, ensuring efficient lookups and comparisons. * * @param _template The string representation of the named type template. * @return A string containing the hash of the named type template. @@ -208,7 +215,8 @@ class InMemoryDB : public AtomDB { /** * @brief Retrieves and deletes the outgoing set associated with a handle. - * @param handle The handle for which the outgoing set is to be retrieved and deleted. + * @param handle The handle for which the outgoing set is to be retrieved and + * deleted. * @return An optional StringList containing the outgoing set if it exists. */ const optional _get_and_delete_outgoing_set(const string& handle); @@ -223,7 +231,8 @@ class InMemoryDB : public AtomDB { /** * @brief Deletes a set of incoming atoms associated with a given link handle. * @param link_handle A string representing the handle of the link. - * @param atoms_handles A list of strings representing the handles of the atoms to be deleted. + * @param atoms_handles A list of strings representing the handles of the + * atoms to be deleted. */ void _delete_incoming_set(const string& link_handle, const StringList& atoms_handles); @@ -239,7 +248,8 @@ class InMemoryDB : public AtomDB { /** * @brief Deletes templates associated with the given document link. - * @param link_document The link to the document whose templates are to be deleted. + * @param link_document The link to the document whose templates are to be + * deleted. */ void _delete_templates(const Link& link_document); @@ -253,8 +263,10 @@ class InMemoryDB : public AtomDB { /** * @brief Deletes patterns from the specified document. - * @param link_document The link to the document from which patterns will be deleted. - * @param targets_hash A list of hashes representing the patterns to be deleted. + * @param link_document The link to the document from which patterns will be + * deleted. + * @param targets_hash A list of hashes representing the patterns to be + * deleted. */ void _delete_patterns(const Link& link_document, const StringList& targets_hash); @@ -267,7 +279,8 @@ class InMemoryDB : public AtomDB { /** * @brief Filters out non-top-level elements from the given set of matches. * @param matches The set of matches to be filtered. - * @return A set containing only the top-level elements from the input matches. + * @return A set containing only the top-level elements from the input + * matches. */ const StringUnorderedSet _filter_non_toplevel(const StringUnorderedSet& matches) const; @@ -286,7 +299,8 @@ class InMemoryDB : public AtomDB { /** * @brief Updates the index for the given atom. * @param atom The atom to update the index for. - * @param delete_atom Flag indicating whether to delete the atom from the index. + * @param delete_atom Flag indicating whether to delete the atom from the + * index. */ void _update_index(const Atom& atom, bool delete_atom = false); }; diff --git a/src/hyperon_das_atomdb_cpp_lib/type_aliases.h b/src/hyperon_das_atomdb_cpp_lib/type_aliases.h index f9525f7..2bd38b8 100644 --- a/src/hyperon_das_atomdb_cpp_lib/type_aliases.h +++ b/src/hyperon_das_atomdb_cpp_lib/type_aliases.h @@ -1,18 +1,20 @@ /** * @file type_aliases.h - * @brief This header file contains type aliases to improve code readability and maintainability - * within the atomdb namespace. + * @brief This header file contains type aliases to improve code readability and + * maintainability within the atomdb namespace. * - * The type aliases defined in this file are intended to simplify the usage of commonly used - * STL containers and types, making the code more concise and easier to understand. The aliases - * cover a range of types including optional values, sets, maps, and lists. + * The type aliases defined in this file are intended to simplify the usage of + * commonly used STL containers and types, making the code more concise and + * easier to understand. The aliases cover a range of types including optional + * values, sets, maps, and lists. * - * @note 1. The alias MapOfAny for std::unordered_map is commented out due - * to poor performance. It is kept in the file as a reminder of the performance implications. - * 2. ListOfAny is an alias for std::vector, representing a list of any type. - * Note that while std::vector can be useful in some cases, its performance - * should be tested for each specific use case. + * @note 1. The alias MapOfAny for std::unordered_map is + * commented out due to poor performance. It is kept in the file as a reminder + * of the performance implications. + * 2. ListOfAny is an alias for std::vector, representing a list + * of any type. Note that while std::vector can be useful in some + * cases, its performance should be tested for each specific use case. */ #pragma once @@ -35,15 +37,17 @@ using StringList = vector; using StringUnorderedSet = unordered_set; /** - * std::vector performs well enough in some particular cases, but be cautious when using it. - * Always test how it performs in your specific use case. + * std::vector performs well enough in some particular cases, but be + * cautious when using it. Always test how it performs in your specific use + * case. */ using ListOfAny = vector; /** * NOTE: - * The following type alias was commented out because std::unordered_map performs - * poorly, and it was kept here just as a reminder of the performance implications. + * The following type alias was commented out because std::unordered_map performs poorly, and it was kept here just as a reminder of the + * performance implications. * * using MapOfAny = unordered_map; */ diff --git a/src/hyperon_das_node/hyperon_das_node_ext.cc b/src/hyperon_das_node/hyperon_das_node_ext.cc index 7d35344..a80ee33 100644 --- a/src/hyperon_das_node/hyperon_das_node_ext.cc +++ b/src/hyperon_das_node/hyperon_das_node_ext.cc @@ -1,16 +1,16 @@ #include +#include #include #include -#include #include #include "distributed_algorithm_node/DistributedAlgorithmNode.h" +#include "distributed_algorithm_node/LeadershipBroker.h" #include "distributed_algorithm_node/Message.h" #include "distributed_algorithm_node/MessageBroker.h" -#include "distributed_algorithm_node/LeadershipBroker.h" namespace nb = nanobind; -using namespace nb::literals; // Enables use of literal "_a" for named arguments +using namespace nb::literals; // Enables use of literal "_a" for named arguments using namespace std; using namespace distributed_algorithm_node; @@ -21,87 +21,89 @@ using MessageFactoryPtr = shared_ptr; // **************************** Python Trampolines **************************** // Trampolines allow Python subclasses to override C++ methods. -// For more information: https://nanobind.readthedocs.io/en/latest/classes.html#overriding-virtual-functions-in-python +// For more information: +// https://nanobind.readthedocs.io/en/latest/classes.html#overriding-virtual-functions-in-python class MessageTrampoline : public Message { - // Defines a trampoline for the BaseClass - // The count (1) denotes the total number of virtual method slots that can be - // overriden within Python. - NB_TRAMPOLINE(Message, 1); - void act(MessageFactoryPtr node) override { - // Allows Python to override a pure virtual method - NB_OVERRIDE_PURE(act, node); - } + // Defines a trampoline for the BaseClass + // The count (1) denotes the total number of virtual method slots that can be + // overriden within Python. + NB_TRAMPOLINE(Message, 1); + void act(MessageFactoryPtr node) override { + // Allows Python to override a pure virtual method + NB_OVERRIDE_PURE(act, node); + } }; class MessageFactoryTrampoline : public MessageFactory { -public: - NB_TRAMPOLINE(MessageFactory, 1); - MessagePtr message_factory(string &command, vector &args) override { - NB_OVERRIDE_PURE(message_factory, command, args); - }; + public: + NB_TRAMPOLINE(MessageFactory, 1); + MessagePtr message_factory(string& command, vector& args) override { + NB_OVERRIDE_PURE(message_factory, command, args); + }; }; class DistributedAlgorithmNodeTrampoline : public DistributedAlgorithmNode { -public: - // Defines a trampoline for the BaseClass - // Since we are overriding 3 methods in Python, thon - NB_TRAMPOLINE(DistributedAlgorithmNode, 3); - MessagePtr message_factory(string &command, vector &args) override { - // Allows Python to override a non pure virtual method - NB_OVERRIDE(message_factory, command, args); - }; - void node_joined_network(const string &node_id) override { - NB_OVERRIDE_PURE(node_joined_network, node_id); - }; - string cast_leadership_vote() override { - NB_OVERRIDE_PURE(cast_leadership_vote); - }; + public: + // Defines a trampoline for the BaseClass + // Since we are overriding 3 methods in Python, thon + NB_TRAMPOLINE(DistributedAlgorithmNode, 3); + MessagePtr message_factory(string& command, vector& args) override { + // Allows Python to override a non pure virtual method + NB_OVERRIDE(message_factory, command, args); + }; + void node_joined_network(const string& node_id) override { + NB_OVERRIDE_PURE(node_joined_network, node_id); + }; + string cast_leadership_vote() override { NB_OVERRIDE_PURE(cast_leadership_vote); }; }; // **************************************************************************** // Create the Python module 'hyperon_das_node_ext' NB_MODULE(hyperon_das_node_ext, m) { + // Message.h bindings + nb::class_(m, "Message") + .def(nb::init<>()) + .def("act", + &Message::act); // Bind the act method (can be overriden in Python) - // Message.h bindings - nb::class_(m, "Message") - .def(nb::init<>()) - .def("act", &Message::act); // Bind the act method (can be overriden in Python) - - nb::class_(m, "MessageFactory") - .def("message_factory", &MessageFactory::message_factory); // Bind the message_factory method (can be overriden in Python) + nb::class_(m, "MessageFactory") + .def("message_factory", + &MessageFactory::message_factory); // Bind the message_factory method + // (can be overriden in Python) - // LeadershipBroker.h bindings - // Binds the enum LeadershipBrokerType and all of it's values. - // Needs to be updated whenever a new LeadershipBrokerType is added. - nb::enum_(m, "LeadershipBrokerType") - .value("SINGLE_MASTER_SERVER", LeadershipBrokerType::SINGLE_MASTER_SERVER); + // LeadershipBroker.h bindings + // Binds the enum LeadershipBrokerType and all of it's values. + // Needs to be updated whenever a new LeadershipBrokerType is added. + nb::enum_(m, "LeadershipBrokerType") + .value("SINGLE_MASTER_SERVER", LeadershipBrokerType::SINGLE_MASTER_SERVER); - // MessageBroker.h bindings - // Binds the enum MessageBrokerType and all of it's values. - // Needs to be updated whenever a new MessageBrokerType is added. - nb::enum_(m, "MessageBrokerType") - .value("GRPC", MessageBrokerType::GRPC) - .value("RAM", MessageBrokerType::RAM); + // MessageBroker.h bindings + // Binds the enum MessageBrokerType and all of it's values. + // Needs to be updated whenever a new MessageBrokerType is added. + nb::enum_(m, "MessageBrokerType") + .value("GRPC", MessageBrokerType::GRPC) + .value("RAM", MessageBrokerType::RAM); - // DistributedAlgorithmNode.h bindings - nb::class_( - m, "DistributedAlgorithmNode") - .def(nb::init(), - "node_id"_a, "leadership_algorithm"_a, "messaging_backend"_a) - .def("join_network", &DistributedAlgorithmNode::join_network) - .def("is_leader", &DistributedAlgorithmNode::is_leader) - .def("leader_id", &DistributedAlgorithmNode::leader_id) - .def("has_leader", &DistributedAlgorithmNode::has_leader) - // Whenever we have a parameter that is a pointer or a reference, we need - // to specify the name of the argument. Otherwise nanobind will add a - // default arg0, arg1, etc. - .def("add_peer", &DistributedAlgorithmNode::add_peer, "peer_id"_a) - .def("node_id", &DistributedAlgorithmNode::node_id) - .def("broadcast", &DistributedAlgorithmNode::broadcast, "command"_a, "args"_a) - .def("send", &DistributedAlgorithmNode::send, "command"_a, "args"_a, "recipient"_a) - .def("node_joined_network", &DistributedAlgorithmNode::node_joined_network, - "node_id"_a) - .def("cast_leadership_vote", &DistributedAlgorithmNode::cast_leadership_vote) - .def("message_factory", &DistributedAlgorithmNode::message_factory); + // DistributedAlgorithmNode.h bindings + nb::class_( + m, "DistributedAlgorithmNode") + .def(nb::init(), + "node_id"_a, + "leadership_algorithm"_a, + "messaging_backend"_a) + .def("join_network", &DistributedAlgorithmNode::join_network) + .def("is_leader", &DistributedAlgorithmNode::is_leader) + .def("leader_id", &DistributedAlgorithmNode::leader_id) + .def("has_leader", &DistributedAlgorithmNode::has_leader) + // Whenever we have a parameter that is a pointer or a reference, we need + // to specify the name of the argument. Otherwise nanobind will add a + // default arg0, arg1, etc. + .def("add_peer", &DistributedAlgorithmNode::add_peer, "peer_id"_a) + .def("node_id", &DistributedAlgorithmNode::node_id) + .def("broadcast", &DistributedAlgorithmNode::broadcast, "command"_a, "args"_a) + .def("send", &DistributedAlgorithmNode::send, "command"_a, "args"_a, "recipient"_a) + .def("node_joined_network", &DistributedAlgorithmNode::node_joined_network, "node_id"_a) + .def("cast_leadership_vote", &DistributedAlgorithmNode::cast_leadership_vote) + .def("message_factory", &DistributedAlgorithmNode::message_factory); } diff --git a/src/inference_agent/inference_agent.h b/src/inference_agent/inference_agent.h index 1e9dc35..f251a19 100644 --- a/src/inference_agent/inference_agent.h +++ b/src/inference_agent/inference_agent.h @@ -3,16 +3,16 @@ */ #pragma once +#include #include #include #include #include #include -#include #include "das_link_creation_node.h" -#include "inference_node.h" #include "inference_iterator.h" +#include "inference_node.h" using namespace distributed_algorithm_node; using namespace link_creation_agent; @@ -23,9 +23,10 @@ class InferenceAgent { InferenceAgent(); ~InferenceAgent(); /** - * @brief Start the agent, receive inference request from the client, send link_creation - * request to the link_creation_agent, listen when distributed inference control agent - * finish the inference, send request to stop link creation. + * @brief Start the agent, receive inference request from the client, send + * link_creation request to the link_creation_agent, listen when distributed + * inference control agent finish the inference, send request to stop link + * creation. */ void run(); void stop(); @@ -47,10 +48,10 @@ class InferenceAgent { std::mutex agent_mutex; InferenceNode* inference_node_server; LinkCreationNode* link_creation_node_client; - std::unordered_map iterator_link_creation_request_map; // iterator_id, link_creation_request + std::unordered_map + iterator_link_creation_request_map; // iterator_id, link_creation_request std::vector>> inference_iterators; // DasAgentNode* das_client; // DistributedInferenceControlNode* distributed_inference_control_node; - }; } // namespace inference_agent diff --git a/src/inference_agent/inference_node.h b/src/inference_agent/inference_node.h index 508748f..5e49c8d 100644 --- a/src/inference_agent/inference_node.h +++ b/src/inference_agent/inference_node.h @@ -24,7 +24,6 @@ class InferenceNode : public StarNode { bool is_answers_empty(); string pop_answer(); - void send_message(std::vector args); virtual std::shared_ptr message_factory(std::string& command, @@ -44,7 +43,6 @@ class InferenceNode : public StarNode { std::mutex agent_node_mutex; }; - class CreateInferenceMessage : public Message { public: CreateInferenceMessage(std::string command, std::vector args); @@ -52,7 +50,6 @@ class CreateInferenceMessage : public Message { void act(std::shared_ptr node) override; }; - class InferenceAnswerMessage : public Message { public: InferenceAnswerMessage(std::string command, std::vector args); @@ -60,7 +57,6 @@ class InferenceAnswerMessage : public Message { void act(std::shared_ptr node) override; }; - class DistributedInferenceFinishedMessage : public Message { public: DistributedInferenceFinishedMessage(std::string command, std::vector args); diff --git a/src/inference_agent/inference_request.h b/src/inference_agent/inference_request.h index 07d3d8e..99749bd 100644 --- a/src/inference_agent/inference_request.h +++ b/src/inference_agent/inference_request.h @@ -72,7 +72,6 @@ class ProofOfImplication : public InferenceRequest { std::vector untokenize() override; std::vector query() override; - private: const std::string IMPLICATION_DEDUCTION_PROCESSOR = "IMPLICATION_DEDUCTION"; }; @@ -86,7 +85,6 @@ class ProofOfEquivalence : public InferenceRequest { std::vector untokenize() override; std::vector query() override; - private: const std::string EQUIVALENCE_DEDUCTION_PROCESSOR = "EQUIVALENCE_DEDUCTION"; }; diff --git a/src/link_creation_agent/das_link_creation_node.cc b/src/link_creation_agent/das_link_creation_node.cc index 8e3c7c4..2d30d79 100644 --- a/src/link_creation_agent/das_link_creation_node.cc +++ b/src/link_creation_agent/das_link_creation_node.cc @@ -4,11 +4,10 @@ using namespace link_creation_agent; using namespace std; using namespace distributed_algorithm_node; -LinkCreationNode::LinkCreationNode(const string& node_id) : StarNode(node_id) { - is_server = true; -} +LinkCreationNode::LinkCreationNode(const string& node_id) : StarNode(node_id) { is_server = true; } -LinkCreationNode::LinkCreationNode(const string& node_id, const string& server_id) : StarNode(node_id, server_id) { +LinkCreationNode::LinkCreationNode(const string& node_id, const string& server_id) + : StarNode(node_id, server_id) { is_server = false; } @@ -39,7 +38,6 @@ shared_ptr LinkCreationNode::message_factory(string& command, vector(command, args); } - void LinkCreationNode::send_message(vector args) { cout << "Sending message" << endl; send(CREATE_LINK, args, server_id); @@ -55,5 +53,3 @@ void LinkCreationRequest::act(shared_ptr node) { string request; link_node->add_request(this->args); } - - diff --git a/src/link_creation_agent/das_link_creation_node.h b/src/link_creation_agent/das_link_creation_node.h index 1af9b04..149a91d 100644 --- a/src/link_creation_agent/das_link_creation_node.h +++ b/src/link_creation_agent/das_link_creation_node.h @@ -20,7 +20,8 @@ class LinkCreationNode : public StarNode { * @param node_id ID of this node in the network. * @param server_id ID of a server. */ - LinkCreationNode(const string& node_id, const string& server_id);; + LinkCreationNode(const string& node_id, const string& server_id); + ; /** * Destructor @@ -57,7 +58,7 @@ class LinkCreationNode : public StarNode { private: Queue> shared_queue; const string CREATE_LINK = "create_link"; // DAS Node command - const string CREATE_LINK_PROCESSOR = "create_link_processor"; + const string CREATE_LINK_PROCESSOR = "create_link_processor"; bool shutting_down = false; bool is_server = true; }; diff --git a/src/link_creation_agent/link.cc b/src/link_creation_agent/link.cc index 839a5f0..3c24df3 100644 --- a/src/link_creation_agent/link.cc +++ b/src/link_creation_agent/link.cc @@ -6,8 +6,6 @@ using namespace link_creation_agent; using namespace std; using namespace query_engine; - - Link::Link(QueryAnswer* query_answer, vector link_template) { LinkCreateTemplate link_create_template(link_template); HandlesAnswer* handles_answer = dynamic_cast(query_answer); @@ -56,10 +54,9 @@ vector Link::get_targets() { return this->targets; } void Link::set_type(string type) { this->type = type; } - void Link::add_target(LinkTargetTypes target) { this->targets.push_back(target); } -vector Link::tokenize() { +vector Link::tokenize() { vector tokens; tokens.push_back("LINK"); tokens.push_back(this->type); diff --git a/src/link_creation_agent/link.h b/src/link_creation_agent/link.h index 46902c2..e1a259c 100644 --- a/src/link_creation_agent/link.h +++ b/src/link_creation_agent/link.h @@ -4,59 +4,56 @@ */ #pragma once #include -#include #include -#include "QueryAnswer.h" +#include + #include "HandlesAnswer.h" +#include "QueryAnswer.h" #include "link_create_template.h" using namespace std; using namespace query_engine; -namespace link_creation_agent -{ - - class Link; // forward declaration - - using LinkTargetTypes = std::variant>; - - class Link - { - public: - Link(QueryAnswer *query_answer, vector link_template); - Link(QueryAnswer *query_answer, shared_ptr link_create_template); - Link(); - ~Link(); - /** - * @brief Get the type of the link - * @returns Returns the type of the link - */ - string get_type(); - /** - * @brief Get the targets of the link - * @returns Returns the targets of the link - */ - vector get_targets(); - /** - * @brief Set the type of the link - */ - void set_type(string type); - /** - * @brief Add a target to the link - * @param target Target to be added - */ - void add_target(LinkTargetTypes target); - /** - * @brief Tokenize the link - * @returns Returns the tokenized link - */ - vector tokenize(); - - private: - string type; - vector targets; - vector custom_fields; - - - }; -} \ No newline at end of file +namespace link_creation_agent { + +class Link; // forward declaration + +using LinkTargetTypes = std::variant>; + +class Link { + public: + Link(QueryAnswer* query_answer, vector link_template); + Link(QueryAnswer* query_answer, shared_ptr link_create_template); + Link(); + ~Link(); + /** + * @brief Get the type of the link + * @returns Returns the type of the link + */ + string get_type(); + /** + * @brief Get the targets of the link + * @returns Returns the targets of the link + */ + vector get_targets(); + /** + * @brief Set the type of the link + */ + void set_type(string type); + /** + * @brief Add a target to the link + * @param target Target to be added + */ + void add_target(LinkTargetTypes target); + /** + * @brief Tokenize the link + * @returns Returns the tokenized link + */ + vector tokenize(); + + private: + string type; + vector targets; + vector custom_fields; +}; +} // namespace link_creation_agent \ No newline at end of file diff --git a/src/link_creation_agent/link_create_template.h b/src/link_creation_agent/link_create_template.h index 30d7d5a..fb99ad4 100644 --- a/src/link_creation_agent/link_create_template.h +++ b/src/link_creation_agent/link_create_template.h @@ -43,13 +43,14 @@ struct Variable { /** * @typedef CustomFieldTypes - * @brief A variant type that can hold either a std::string or a std::shared_ptr to a CustomField. + * @brief A variant type that can hold either a std::string or a std::shared_ptr + * to a CustomField. */ using CustomFieldTypes = std::variant>; /** * @typedef LinkCreateTemplateTypes - * @brief A variant type that can hold either a Variable, Node, or a std::shared_ptr to a - * LinkCreateTemplate. + * @brief A variant type that can hold either a Variable, Node, or a + * std::shared_ptr to a LinkCreateTemplate. */ using LinkCreateTemplateTypes = std::variant>; @@ -60,7 +61,8 @@ using LinkCreateTemplateTypes = std::variant& custom_fields); /** @@ -74,7 +76,8 @@ class CustomField { std::string get_name(); /** * @brief Gets the values of the custom field. - * @return A vector of tuples containing the name and value of the custom field. + * @return A vector of tuples containing the name and value of the custom + * field. */ std::vector> get_values(); /** @@ -95,12 +98,14 @@ class CustomField { /** * @class LinkCreateTemplate - * @brief Represents a link creation template with a link type, targets, and custom fields. + * @brief Represents a link creation template with a link type, targets, and + * custom fields. */ class LinkCreateTemplate { public: /** - * @brief Constructor that initializes the link creation template with a list of link templates. + * @brief Constructor that initializes the link creation template with a list + * of link templates. */ LinkCreateTemplate(std::vector& link_template); /** @@ -130,7 +135,8 @@ class LinkCreateTemplate { /** * @brief Tokenizes the link creation template. - * @return A vector of strings representing the tokenized link creation template. + * @return A vector of strings representing the tokenized link creation + * template. */ std::vector tokenize(); diff --git a/src/link_creation_agent/link_creation_agent.h b/src/link_creation_agent/link_creation_agent.h index da23bf5..4efa69f 100644 --- a/src/link_creation_agent/link_creation_agent.h +++ b/src/link_creation_agent/link_creation_agent.h @@ -40,11 +40,13 @@ struct LinkCreationAgentRequest { /** * @class LinkCreationAgent - * @brief Manages the creation of links by processing requests from the DAS Node server or buffer. + * @brief Manages the creation of links by processing requests from the DAS Node + * server or buffer. * - * This class is responsible for retrieving requests, sending query requests, processing iterators, - * and creating links using the LCAService. It also handles loading and saving configurations and - * request buffers, and managing the lifecycle of the agent. + * This class is responsible for retrieving requests, sending query requests, + * processing iterators, and creating links using the LCAService. It also + * handles loading and saving configurations and request buffers, and managing + * the lifecycle of the agent. */ class LinkCreationAgent { public: @@ -52,9 +54,10 @@ class LinkCreationAgent { ~LinkCreationAgent(); /** - * @brief Retrieve a request from DAS Node server or get a request from the requests buffer, - * send a query request using DAS Node client, retrieve remote iterator and - * send to LCAService to process the iterator and create links. + * @brief Retrieve a request from DAS Node server or get a request from the + * requests buffer, send a query request using DAS Node client, retrieve + * remote iterator and send to LCAService to process the iterator and create + * links. */ void run(); /** @@ -66,7 +69,8 @@ class LinkCreationAgent { private: /** * @brief Sends a query to DAS Query Agent - * @returns Returns a shared_ptr, to iterate through the requests + * @returns Returns a shared_ptr, to iterate through the + * requests */ shared_ptr> query(vector& query_tokens, string context, @@ -76,11 +80,13 @@ class LinkCreationAgent { */ void load_config(); /** - * @brief Save all requests that have the infinite value set as true to the disk or DB. + * @brief Save all requests that have the infinite value set as true to the + * disk or DB. */ void save_buffer(); /** - * @brief Load all requests that have the infinite value set as true from the disk or DB. + * @brief Load all requests that have the infinite value set as true from the + * disk or DB. */ void load_buffer(); /** @@ -97,8 +103,8 @@ class LinkCreationAgent { string link_creation_agent_server_id; // ID of the link creation server string das_agent_client_id; // ID of the DAS client string das_agent_server_id; - string requests_buffer_file; // Path to the requests buffer file - string context; // Context to send to attention broker + string requests_buffer_file; // Path to the requests buffer file + string context; // Context to send to attention broker // Other attributes LinkCreationService* service; diff --git a/src/link_creation_agent/queue.h b/src/link_creation_agent/queue.h index 9c80491..213435c 100644 --- a/src/link_creation_agent/queue.h +++ b/src/link_creation_agent/queue.h @@ -6,31 +6,27 @@ template class Queue { -private: + private: std::queue m_queue; std::mutex m_mutex; std::condition_variable m_cond; -public: - void enqueue(T item) - { - + public: + void enqueue(T item) { std::unique_lock lock(m_mutex); m_queue.push(item); m_cond.notify_one(); } - T dequeue() - { + T dequeue() { std::unique_lock lock(m_mutex); - m_cond.wait(lock, - [this]() { return !m_queue.empty(); }); + m_cond.wait(lock, [this]() { return !m_queue.empty(); }); T item = m_queue.front(); m_queue.pop(); return item; } - bool empty(){ + bool empty() { bool answer; std::unique_lock lock(m_mutex); answer = m_queue.empty(); diff --git a/src/main/attention_broker_main.cc b/src/main/attention_broker_main.cc index a85bd84..fc8aca1 100644 --- a/src/main/attention_broker_main.cc +++ b/src/main/attention_broker_main.cc @@ -1,19 +1,17 @@ -#include -#include - #include #include #include - #include -#include "common.pb.h" -#include "attention_broker.grpc.pb.h" -#include "attention_broker.pb.h" +#include +#include #include "AttentionBrokerServer.h" +#include "attention_broker.grpc.pb.h" +#include "attention_broker.pb.h" +#include "common.pb.h" -//attention_broker_server::AttentionBrokerServer service; +// attention_broker_server::AttentionBrokerServer service; /* void ctrl_c_handler(int) { @@ -27,8 +25,8 @@ void ctrl_c_handler(int) { void run_server(unsigned int port) { attention_broker_server::AttentionBrokerServer service; std::string server_address = "localhost:" + to_string(port); - //grpc::EnableDefaultHealthCheckService(true); - //grpc::reflection::InitProtoReflectionServerBuilderPlugin(); + // grpc::EnableDefaultHealthCheckService(true); + // grpc::reflection::InitProtoReflectionServerBuilderPlugin(); ServerBuilder builder; builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); builder.RegisterService(&service); @@ -44,7 +42,7 @@ int main(int argc, char* argv[]) { exit(1); } unsigned int port = stoi(argv[1]); - //signal(SIGINT, &ctrl_c_handler); + // signal(SIGINT, &ctrl_c_handler); run_server(port); return 0; } diff --git a/src/main/inference_agent_main.cc b/src/main/inference_agent_main.cc index 2d7aeea..965ed82 100644 --- a/src/main/inference_agent_main.cc +++ b/src/main/inference_agent_main.cc @@ -2,7 +2,6 @@ using namespace inference_agent; - int main() { // InferenceAgent agent; // agent.run(); diff --git a/src/main/link_creation_agent_client_main.cc b/src/main/link_creation_agent_client_main.cc index afeab4a..2c45d52 100644 --- a/src/main/link_creation_agent_client_main.cc +++ b/src/main/link_creation_agent_client_main.cc @@ -14,7 +14,6 @@ void ctrl_c_handler(int) { exit(0); } - int main(int argc, char* argv[]) { string help = R""""( Usage: link_creation_agent CLIENT_HOST:CLIENT_PORT SERVER_HOST:SERVER_PORT REQUEST+ diff --git a/src/main/link_creation_agent_main.cc b/src/main/link_creation_agent_main.cc index 8504889..a02c1b2 100644 --- a/src/main/link_creation_agent_main.cc +++ b/src/main/link_creation_agent_main.cc @@ -1,7 +1,8 @@ -#include -#include #include + #include +#include +#include #include "link_creation_agent.h" using namespace link_creation_agent; @@ -13,8 +14,6 @@ void ctrl_c_handler(int) { exit(0); } - - /** * @brief Main function * Reads the config file and starts the DAS NODE client/server @@ -22,8 +21,7 @@ void ctrl_c_handler(int) { * @param argv Arguments * @returns Returns 0 if the program runs successfully */ -int main(int argc, char *argv[]) -{ +int main(int argc, char* argv[]) { string help = R""""( Usage: link_creation_agent --config_file --type Suported args: @@ -37,12 +35,10 @@ int main(int argc, char *argv[]) QUERY, LINK_TEMPLATE, MAX_RESULTS, REPEAT MAX_RESULTS and REPEAT are optional, the default value for MAX_RESULTS is 1000 and for REPEAT is 1 )""""; - - if ((argc < 4) ) - { + + if ((argc < 4)) { cerr << help << endl; - for (auto arg = 0; arg < argc; arg++) - { + for (auto arg = 0; arg < argc; arg++) { cerr << "arg[" << arg << "] = " << argv[arg] << endl; } exit(1); @@ -50,13 +46,10 @@ int main(int argc, char *argv[]) signal(SIGINT, &ctrl_c_handler); string type = argv[2]; string config_path = argv[4]; - - if (type == "client") - { + + if (type == "client") { cerr << "Client not implemented yet" << endl; - } - else - { + } else { cout << "Starting server" << endl; auto server = new LinkCreationAgent(config_path); server->run(); diff --git a/src/main/link_creation_engine_main.cc b/src/main/link_creation_engine_main.cc index 5638695..0742031 100644 --- a/src/main/link_creation_engine_main.cc +++ b/src/main/link_creation_engine_main.cc @@ -1,14 +1,14 @@ +#include + #include -#include #include +#include -#include - +#include "AtomDB.h" +#include "AtomDBSingleton.h" #include "DASNode.h" -#include "RemoteIterator.h" #include "QueryAnswer.h" -#include "AtomDBSingleton.h" -#include "AtomDB.h" +#include "RemoteIterator.h" #include "Utils.h" #define MAX_QUERY_ANSWERS ((unsigned int) 1000) @@ -35,8 +35,7 @@ std::vector split(string s, string delimiter) { return tokens; } -double compute_sim1(const vector &tokens1, const vector &tokens2) { - +double compute_sim1(const vector& tokens1, const vector& tokens2) { unsigned int count = 0; /* @@ -55,8 +54,8 @@ double compute_sim1(const vector &tokens1, const vector &tokens2 } */ - for (auto token1: tokens1) { - for (auto token2: tokens2) { + for (auto token1 : tokens1) { + for (auto token2 : tokens2) { if (token1 == token2) { count++; break; @@ -64,8 +63,8 @@ double compute_sim1(const vector &tokens1, const vector &tokens2 } } - for (auto token2: tokens2) { - for (auto token1: tokens1) { + for (auto token2 : tokens2) { + for (auto token1 : tokens1) { if (token2 == token1) { count++; break; @@ -76,8 +75,7 @@ double compute_sim1(const vector &tokens1, const vector &tokens2 return ((1.0) * count) / (tokens1.size() + tokens2.size()); } -double compute_sim2(const vector &tokens1, const vector &tokens2) { - +double compute_sim2(const vector& tokens1, const vector& tokens2) { if (tokens1.size() != tokens2.size()) { return 0.0; } @@ -94,15 +92,17 @@ double compute_sim2(const vector &tokens1, const vector &tokens2 return (1.0 * count) / total_length; } -string highlight(const vector &tokens1, const vector &tokens2, const set &highlighted) { - //printf("\033[31;1;4mHello\033[0m"); +string highlight(const vector& tokens1, + const vector& tokens2, + const set& highlighted) { + // printf("\033[31;1;4mHello\033[0m"); string answer = ""; bool token_flag, char_flag, word_flag; for (unsigned int i = 0; i < tokens1.size(); i++) { token_flag = (highlighted.find(tokens1[i]) != highlighted.end()); word_flag = false; if (highlighted.size() == 0) { - for (auto token: tokens2) { + for (auto token : tokens2) { if (tokens1[i] == token) { word_flag = true; break; @@ -115,7 +115,7 @@ string highlight(const vector &tokens1, const vector &tokens2, c } else { char_flag = false; } - char_flag = false; // XXXXX + char_flag = false; // XXXXX if (token_flag || char_flag || word_flag) { answer += "\033["; if (token_flag) { @@ -147,8 +147,12 @@ string highlight(const vector &tokens1, const vector &tokens2, c return answer; } -void build_link(const string &link_type_tag, const string str1, const string str2, double threshold, stack &output, const set &highlighted) { - +void build_link(const string& link_type_tag, + const string str1, + const string str2, + double threshold, + stack& output, + const set& highlighted) { string sentence1 = str1.substr(1, str1.size() - 2); string sentence2 = str2.substr(1, str2.size() - 2); @@ -156,21 +160,21 @@ void build_link(const string &link_type_tag, const string str1, const string str vector tokens2 = split(sentence2, " "); double v1 = compute_sim1(tokens1, tokens2); - //double v2 = compute_sim2(tokens1, tokens2); + // double v2 = compute_sim2(tokens1, tokens2); if (v1 >= threshold) { - //output.push(std::to_string(v1) + ": " + highlight(tokens1, tokens2, highlighted)); - //output.push(std::to_string(v2) + ": " + highlight(tokens2, tokens1, highlighted)); + // output.push(std::to_string(v1) + ": " + highlight(tokens1, tokens2, + // highlighted)); output.push(std::to_string(v2) + ": " + highlight(tokens2, + // tokens1, highlighted)); output.push(highlight(tokens1, tokens2, highlighted)); output.push(highlight(tokens2, tokens1, highlighted)); } } -string handle_to_atom(const char *handle) { - +string handle_to_atom(const char* handle) { shared_ptr db = AtomDBSingleton::get_instance(); shared_ptr document = db->get_atom_document(handle); - shared_ptr targets = db->query_for_targets((char *) handle); + shared_ptr targets = db->query_for_targets((char*) handle); string answer; if (targets != NULL) { @@ -197,11 +201,7 @@ string handle_to_atom(const char *handle) { return answer; } -void run( - const string &context, - const string &link_type_tag, - const set highlighted) { - +void run(const string& context, const string& link_type_tag, const set highlighted) { string server_id = "localhost:31700"; string client_id = "localhost:31701"; @@ -229,30 +229,29 @@ void run( // (Contains (Sentence "aef cbe dfb fbe eca eff bad") (Word "eff")) vector query_same_word = { - and_operator, "2", - link_template, expression, "3", - node, symbol, contains, - variable, sentence1, - variable, word1, - link_template, expression, "3", - node, symbol, contains, - variable, sentence2, - variable, word1 - }; - - vector query_same_size { - or_operator, "1", - link_template, expression, "4", - node, symbol, similarity, - variable, sentence1, - variable, sentence2, - variable, tv1 - }; + and_operator, "2", link_template, expression, "3", node, symbol, contains, + variable, sentence1, variable, word1, link_template, expression, "3", node, + symbol, contains, variable, sentence2, variable, word1}; + + vector query_same_size{or_operator, + "1", + link_template, + expression, + "4", + node, + symbol, + similarity, + variable, + sentence1, + variable, + sentence2, + variable, + tv1}; DASNode client(client_id, server_id); - QueryAnswer *query_answer; + QueryAnswer* query_answer; unsigned int count = 0; - RemoteIterator *response; + RemoteIterator* response; if (link_type_tag == "LINK1") { response = client.pattern_matcher_query(query_same_word, context); @@ -268,23 +267,24 @@ void run( shared_ptr sentence_symbol_document2; stack output; set already_inserted_links; - while (! response->finished()) { + while (!response->finished()) { if ((query_answer = response->pop()) == NULL) { Utils::sleep(); } else { - if (! strcmp(query_answer->assignment.get(sentence1.c_str()), query_answer->assignment.get(sentence2.c_str()))) { + if (!strcmp(query_answer->assignment.get(sentence1.c_str()), + query_answer->assignment.get(sentence2.c_str()))) { continue; } - //cout << query_answer->to_string() << endl; - //cout << handle_to_atom(query_answer->handles[0]) << endl; - //cout << handle_to_atom(query_answer->handles[1]) << endl; + // cout << query_answer->to_string() << endl; + // cout << handle_to_atom(query_answer->handles[0]) << endl; + // cout << handle_to_atom(query_answer->handles[1]) << endl; sentence_document1 = db->get_atom_document(query_answer->assignment.get(sentence1.c_str())); sentence_document2 = db->get_atom_document(query_answer->assignment.get(sentence2.c_str())); sentence_symbol_document1 = db->get_atom_document(sentence_document1->get("targets", 1)); sentence_symbol_document2 = db->get_atom_document(sentence_document2->get("targets", 1)); string s1 = string(sentence_symbol_document1->get("name")); string s2 = string(sentence_symbol_document2->get("name")); - if ((already_inserted_links.find(s1 + s2) == already_inserted_links.end()) && + if ((already_inserted_links.find(s1 + s2) == already_inserted_links.end()) && (already_inserted_links.find(s2 + s1) == already_inserted_links.end())) { build_link(link_type_tag, s1, s2, 0.0, output, highlighted); already_inserted_links.insert(s1 + s2); @@ -299,7 +299,7 @@ void run( if (count == 0) { cout << "No match for query" << endl; } else { - while (! output.empty()) { + while (!output.empty()) { cout << output.top() << endl; output.pop(); cout << output.top() << endl; @@ -312,7 +312,6 @@ void run( } int main(int argc, char* argv[]) { - if (argc < 3) { cerr << "Usage: " << argv[0] << " *" << endl; exit(1); diff --git a/src/main/query_client_main.cc b/src/main/query_client_main.cc index 3759e6d..5f87983 100644 --- a/src/main/query_client_main.cc +++ b/src/main/query_client_main.cc @@ -1,13 +1,13 @@ +#include + #include #include -#include - +#include "AtomDBSingleton.h" #include "DASNode.h" -#include "RemoteIterator.h" -#include "QueryAnswer.h" #include "HandlesAnswer.h" -#include "AtomDBSingleton.h" +#include "QueryAnswer.h" +#include "RemoteIterator.h" #include "Utils.h" #define MAX_QUERY_ANSWERS ((unsigned int) 1000) @@ -21,9 +21,12 @@ void ctrl_c_handler(int) { } int main(int argc, char* argv[]) { - if (argc < 4) { - cerr << "Usage: " << argv[0] << " CLIENT_HOST:CLIENT_PORT SERVER_HOST:SERVER_PORT QUERY_TOKEN+ (hosts are supposed to be public IPs or known hostnames)" << endl; + cerr << "Usage: " << argv[0] + << " CLIENT_HOST:CLIENT_PORT SERVER_HOST:SERVER_PORT QUERY_TOKEN+ " + "(hosts are supposed to " + "be public IPs or known hostnames)" + << endl; exit(1); } @@ -37,10 +40,10 @@ int main(int argc, char* argv[]) { } DASNode client(client_id, server_id); - QueryAnswer *query_answer; + QueryAnswer* query_answer; unsigned int count = 0; - RemoteIterator *response = client.pattern_matcher_query(query); - while (! response->finished()) { + RemoteIterator* response = client.pattern_matcher_query(query); + while (!response->finished()) { if ((query_answer = response->pop()) == NULL) { Utils::sleep(); } else { diff --git a/src/main/query_engine_main.cc b/src/main/query_engine_main.cc index c60f71c..3f5ac80 100644 --- a/src/main/query_engine_main.cc +++ b/src/main/query_engine_main.cc @@ -1,23 +1,22 @@ +#include + #include #include -#include - #include "AtomDBSingleton.h" -#include "Utils.h" #include "DASNode.h" +#include "Utils.h" using namespace std; void ctrl_c_handler(int) { - //std::cout << "Stopping query engine server..." << std::endl; + // std::cout << "Stopping query engine server..." << std::endl; std::cout << "Cleaning GRPC buffers..." << std::endl; std::cout << "Done." << std::endl; exit(0); } int main(int argc, char* argv[]) { - if (argc != 2) { cerr << "Usage: " << argv[0] << "" << endl; exit(1); @@ -27,7 +26,9 @@ int main(int argc, char* argv[]) { signal(SIGINT, &ctrl_c_handler); AtomDBSingleton::init(); DASNode server(server_id); - cout << "############################# REQUEST QUEUE EMPTY ##################################" << endl; + cout << "############################# REQUEST QUEUE EMPTY " + "##################################" + << endl; do { Utils::sleep(1000); } while (true); diff --git a/src/main/word_query_main.cc b/src/main/word_query_main.cc index de3b887..10aca6b 100644 --- a/src/main/word_query_main.cc +++ b/src/main/word_query_main.cc @@ -1,14 +1,14 @@ +#include + #include #include -#include - +#include "AtomDB.h" +#include "AtomDBSingleton.h" +#include "CountAnswer.h" #include "DASNode.h" -#include "RemoteIterator.h" #include "HandlesAnswer.h" -#include "CountAnswer.h" -#include "AtomDBSingleton.h" -#include "AtomDB.h" +#include "RemoteIterator.h" #include "Utils.h" #define MAX_QUERY_ANSWERS ((unsigned int) 500) @@ -35,7 +35,7 @@ std::vector split(string s, string delimiter) { return tokens; } -string highlight(const string &s, const set &highlighted) { +string highlight(const string& s, const set& highlighted) { vector tokens = split(s.substr(1, s.size() - 2), " "); string answer = ""; for (unsigned int i = 0; i < tokens.size(); i++) { @@ -52,13 +52,10 @@ string highlight(const string &s, const set &highlighted) { return answer; } - - -string handle_to_atom(const char *handle) { - +string handle_to_atom(const char* handle) { shared_ptr db = AtomDBSingleton::get_instance(); shared_ptr document = db->get_atom_document(handle); - shared_ptr targets = db->query_for_targets((char *) handle); + shared_ptr targets = db->query_for_targets((char*) handle); string answer; if (targets != NULL) { @@ -85,10 +82,7 @@ string handle_to_atom(const char *handle) { return answer; } -void run( - const string &context, - const string &word_tag) { - +void run(const string& context, const string& word_tag) { string server_id = "localhost:31700"; string client_id = "localhost:31701"; @@ -110,38 +104,47 @@ void run( string word1 = "word1"; string word2 = "word2"; - vector query_word = { - link_template, expression, "3", - node, symbol, contains, - variable, sentence1, - link, expression, "2", - node, symbol, word, - node, symbol, "\"" + word_tag + "\"" - }; + vector query_word = {link_template, + expression, + "3", + node, + symbol, + contains, + variable, + sentence1, + link, + expression, + "2", + node, + symbol, + word, + node, + symbol, + "\"" + word_tag + "\""}; DASNode client(client_id, server_id); - - HandlesAnswer *query_answer; + + HandlesAnswer* query_answer; unsigned int count = 0; auto response = unique_ptr>( client.pattern_matcher_query(query_word, context, true)); shared_ptr sentence_document; shared_ptr sentence_name_document; vector sentences; - while (! response->finished()) { + while (!response->finished()) { if ((query_answer = dynamic_cast(response->pop())) == NULL) { Utils::sleep(); } else { - //cout << "------------------------------------------" << endl; - //cout << query_answer->to_string() << endl; - const char *handle; + // cout << "------------------------------------------" << endl; + // cout << query_answer->to_string() << endl; + const char* handle; handle = query_answer->assignment.get(sentence1.c_str()); - //cout << string(handle) << endl; - //cout << handle_to_atom(handle) << endl; + // cout << string(handle) << endl; + // cout << handle_to_atom(handle) << endl; sentence_document = db->get_atom_document(handle); handle = sentence_document->get("targets", 1); - //cout << string(handle) << endl; - //cout << handle_to_atom(handle) << endl; + // cout << string(handle) << endl; + // cout << handle_to_atom(handle) << endl; sentence_name_document = db->get_atom_document(handle); // cout << string(sentence_name_document->get("name")) << endl; set to_highlight; @@ -149,11 +152,8 @@ void run( string sentence_name = string(sentence_name_document->get("name")); string highlighted_sentence_name = highlight(sentence_name, to_highlight); string w = "\"" + word_tag + "\""; - string line = "(Contains (Sentence " + - highlighted_sentence_name + - ") (Word \"" + - highlight(w, to_highlight) + - "\"))"; + string line = "(Contains (Sentence " + highlighted_sentence_name + ") (Word \"" + + highlight(w, to_highlight) + "\"))"; cout << line << endl; if (++count == MAX_QUERY_ANSWERS) { break; @@ -172,7 +172,6 @@ void run( } int main(int argc, char* argv[]) { - if (argc < 3) { cerr << "Usage: " << argv[0] << " " << endl; exit(1); diff --git a/src/query_engine/AtomDB.cc b/src/query_engine/AtomDB.cc index cd62f9b..aa8680a 100644 --- a/src/query_engine/AtomDB.cc +++ b/src/query_engine/AtomDB.cc @@ -1,13 +1,15 @@ -#include +#include "AtomDB.h" + +#include + #include -#include +#include #include -#include "AtomDB.h" -#include "Utils.h" +#include #include "AttentionBrokerServer.h" +#include "Utils.h" #include "attention_broker.grpc.pb.h" -#include #include "attention_broker.pb.h" using namespace query_engine; @@ -34,20 +36,18 @@ AtomDB::~AtomDB() { redisFree(this->redis_single); } delete this->mongodb_pool; - // delete this->mongodb_client; + // delete this->mongodb_client; } void AtomDB::attention_broker_setup() { - grpc::ClientContext context; grpc::Status status; dasproto::Empty empty; dasproto::Ack ack; string attention_broker_address = "localhost:37007"; - auto stub = dasproto::AttentionBroker::NewStub(grpc::CreateChannel( - attention_broker_address, - grpc::InsecureChannelCredentials())); + auto stub = dasproto::AttentionBroker::NewStub( + grpc::CreateChannel(attention_broker_address, grpc::InsecureChannelCredentials())); status = stub->ping(&context, empty, &ack); if (status.ok()) { std::cout << "Connected to AttentionBroker at " << attention_broker_address << endl; @@ -60,7 +60,6 @@ void AtomDB::attention_broker_setup() { } void AtomDB::redis_setup() { - string host = Utils::get_environment("DAS_REDIS_HOSTNAME"); string port = Utils::get_environment("DAS_REDIS_PORT"); string address = host + ":" + port; @@ -69,7 +68,10 @@ void AtomDB::redis_setup() { this->cluster_flag = (cluster == "TRUE"); if (host == "" || port == "") { - Utils::error("You need to set Redis access info as environment variables: DAS_REDIS_HOSTNAME, DAS_REDIS_PORT and DAS_USE_REDIS_CLUSTER"); + Utils::error( + "You need to set Redis access info as environment variables: " + "DAS_REDIS_HOSTNAME, " + "DAS_REDIS_PORT and DAS_USE_REDIS_CLUSTER"); } string cluster_tag = (this->cluster_flag ? "CLUSTER" : "NON-CLUSTER"); @@ -83,7 +85,7 @@ void AtomDB::redis_setup() { if (this->redis_cluster == NULL && this->redis_single == NULL) { Utils::error("Connection error."); - } else if ((! this->cluster_flag) && this->redis_single->err) { + } else if ((!this->cluster_flag) && this->redis_single->err) { Utils::error("Redis error: " + string(this->redis_single->errstr)); } else if (this->cluster_flag && this->redis_cluster->err) { Utils::error("Redis cluster error: " + string(this->redis_cluster->errstr)); @@ -92,20 +94,20 @@ void AtomDB::redis_setup() { } } -mongocxx::database AtomDB::get_database(){ +mongocxx::database AtomDB::get_database() { auto database = this->mongodb_pool->acquire(); return database[MONGODB_DB_NAME]; } void AtomDB::mongodb_setup() { - string host = Utils::get_environment("DAS_MONGODB_HOSTNAME"); string port = Utils::get_environment("DAS_MONGODB_PORT"); string user = Utils::get_environment("DAS_MONGODB_USERNAME"); string password = Utils::get_environment("DAS_MONGODB_PASSWORD"); if (host == "" || port == "" || user == "" || password == "") { - Utils::error(string("You need to set MongoDB access info as environment variables: ") + \ - "DAS_MONGODB_HOSTNAME, DAS_MONGODB_PORT, DAS_MONGODB_USERNAME and DAS_MONGODB_PASSWORD"); + Utils::error(string("You need to set MongoDB access info as environment variables: ") + + "DAS_MONGODB_HOSTNAME, DAS_MONGODB_PORT, DAS_MONGODB_USERNAME and " + "DAS_MONGODB_PASSWORD"); } string address = host + ":" + port; string url = "mongodb://" + user + ":" + password + "@" + address; @@ -118,11 +120,13 @@ void AtomDB::mongodb_setup() { // this->mongodb_client = new mongocxx::client(uri); // this->mongodb = (*this->mongodb_client)[MONGODB_DB_NAME]; - const auto ping_cmd = bsoncxx::builder::basic::make_document(bsoncxx::builder::basic::kvp("ping", 1)); + const auto ping_cmd = + bsoncxx::builder::basic::make_document(bsoncxx::builder::basic::kvp("ping", 1)); this->mongodb.run_command(ping_cmd.view()); this->mongodb_collection = this->mongodb[MONGODB_COLLECTION_NAME]; - //auto atom_count = this->mongodb_collection.count_documents({}); - //std::cout << "Connected to MongoDB at " << address << " Atom count: " << atom_count << endl; + // auto atom_count = this->mongodb_collection.count_documents({}); + // std::cout << "Connected to MongoDB at " << address << " Atom count: " << + // atom_count << endl; std::cout << "Connected to MongoDB at " << address << endl; } catch (const std::exception& e) { Utils::error(e.what()); @@ -130,14 +134,16 @@ void AtomDB::mongodb_setup() { } shared_ptr AtomDB::query_for_pattern(shared_ptr pattern_handle) { - redisReply *reply = (redisReply *) redisCommand(this->redis_single, "SMEMBERS %s:%s", REDIS_PATTERNS_PREFIX.c_str(), pattern_handle.get()); + redisReply* reply = (redisReply*) redisCommand( + this->redis_single, "SMEMBERS %s:%s", REDIS_PATTERNS_PREFIX.c_str(), pattern_handle.get()); if (reply == NULL) { Utils::error("Redis error"); } if (reply->type != REDIS_REPLY_SET && reply->type != REDIS_REPLY_ARRAY) { Utils::error("Invalid Redis response: " + std::to_string(reply->type)); } - // NOTE: Intentionally, we aren't destroying 'reply' objects.'reply' objects are destroyed in ~RedisSet(). + // NOTE: Intentionally, we aren't destroying 'reply' objects.'reply' objects + // are destroyed in ~RedisSet(). return shared_ptr(new atomdb_api_types::RedisSet(reply)); } @@ -145,8 +151,9 @@ shared_ptr AtomDB::query_for_targets(shared_ptr AtomDB::query_for_targets(char *link_handle_ptr) { - redisReply *reply = (redisReply *) redisCommand(this->redis_single, "GET %s:%s", REDIS_TARGETS_PREFIX.c_str(), link_handle_ptr); +shared_ptr AtomDB::query_for_targets(char* link_handle_ptr) { + redisReply* reply = (redisReply*) redisCommand( + this->redis_single, "GET %s:%s", REDIS_TARGETS_PREFIX.c_str(), link_handle_ptr); /* if (reply == NULL) { Utils::error("Redis error"); @@ -157,19 +164,21 @@ shared_ptr AtomDB::query_for_targets(char *link_ha } if (reply->type != REDIS_REPLY_STRING) { Utils::error("Invalid Redis response: " + std::to_string(reply->type) + - " != " + std::to_string(REDIS_REPLY_STRING)); + " != " + std::to_string(REDIS_REPLY_STRING)); } - // NOTE: Intentionally, we aren't destroying 'reply' objects.'reply' objects are destroyed in ~RedisSet(). - return shared_ptr(new atomdb_api_types::RedisStringBundle(reply)); + // NOTE: Intentionally, we aren't destroying 'reply' objects.'reply' objects + // are destroyed in ~RedisSet(). + return shared_ptr( + new atomdb_api_types::RedisStringBundle(reply)); } -shared_ptr AtomDB::get_atom_document(const char *handle) { +shared_ptr AtomDB::get_atom_document(const char* handle) { this->mongodb_mutex.lock(); auto mongodb_collection = get_database()[MONGODB_COLLECTION_NAME]; - auto reply = mongodb_collection.find_one( - bsoncxx::v_noabi::builder::basic::make_document( - bsoncxx::v_noabi::builder::basic::kvp(MONGODB_FIELD_NAME[MONGODB_FIELD::ID], handle))); - //cout << bsoncxx::to_json(*reply) << endl; // Note to reviewer: please let this dead code here + auto reply = mongodb_collection.find_one(bsoncxx::v_noabi::builder::basic::make_document( + bsoncxx::v_noabi::builder::basic::kvp(MONGODB_FIELD_NAME[MONGODB_FIELD::ID], handle))); + // cout << bsoncxx::to_json(*reply) << endl; // Note to reviewer: please let + // this dead code here this->mongodb_mutex.unlock(); return shared_ptr(new atomdb_api_types::MongodbDocument(reply)); } diff --git a/src/query_engine/AtomDB.h b/src/query_engine/AtomDB.h index 9a62b72..b039409 100644 --- a/src/query_engine/AtomDB.h +++ b/src/query_engine/AtomDB.h @@ -1,45 +1,44 @@ #ifndef _QUERY_ENGINE_ATOMDB_H #define _QUERY_ENGINE_ATOMDB_H -#include -#include -#include #include + #include +#include #include -#include #include +#include +#include +#include + #include "AtomDBAPITypes.h" using namespace std; namespace query_engine { - -enum MONGODB_FIELD { - ID = 0, - size -}; +enum MONGODB_FIELD { ID = 0, size }; // ------------------------------------------------------------------------------------------------- // NOTE TO REVIEWER: // -// This class will be replaced/integrated by/with classes already implemented in das-atom-db. -// -// However, that classes will need to be revisited in order to allow the methods implemented here -// because although the design of such methods is nasty, they have the string advantage of -// allowing the reuse of structures allocated by the DBMS (Redis an MongoDB) withpout the need -// of re-allocation of other dataclasses. Although this nasty behavior may not be desirable -// outside the DAS bounds, it's quite appealing inside the query engine (and perhaps other +// This class will be replaced/integrated by/with classes already implemented in +// das-atom-db. +// +// However, that classes will need to be revisited in order to allow the methods +// implemented here because although the design of such methods is nasty, they +// have the string advantage of allowing the reuse of structures allocated by +// the DBMS (Redis an MongoDB) withpout the need of re-allocation of other +// dataclasses. Although this nasty behavior may not be desirable outside the +// DAS bounds, it's quite appealing inside the query engine (and perhaps other // parts of internal stuff). // -// I think it's pointless to make any further documentation while we don't make this integrfation. +// I think it's pointless to make any further documentation while we don't make +// this integrfation. // ------------------------------------------------------------------------------------------------- class AtomDB { - -public: - + public: AtomDB(); ~AtomDB(); @@ -61,19 +60,18 @@ class AtomDB { shared_ptr query_for_pattern(shared_ptr pattern_handle); shared_ptr query_for_targets(shared_ptr link_handle); - shared_ptr query_for_targets(char *link_handle_ptr); - shared_ptr get_atom_document(const char *handle); - -private: + shared_ptr query_for_targets(char* link_handle_ptr); + shared_ptr get_atom_document(const char* handle); + private: bool cluster_flag; - redisClusterContext *redis_cluster; - redisContext *redis_single; - mongocxx::client *mongodb_client; + redisClusterContext* redis_cluster; + redisContext* redis_single; + mongocxx::client* mongodb_client; mongocxx::database mongodb; mongocxx::v_noabi::collection mongodb_collection; mutex mongodb_mutex; - mongocxx::pool *mongodb_pool; + mongocxx::pool* mongodb_pool; mongocxx::database get_database(); @@ -82,6 +80,6 @@ class AtomDB { void attention_broker_setup(); }; -} // namespace query_engine +} // namespace query_engine -#endif // _QUERY_ENGINE_ATOMDB_H +#endif // _QUERY_ENGINE_ATOMDB_H diff --git a/src/query_engine/AtomDBAPITypes.cc b/src/query_engine/AtomDBAPITypes.cc index 2d1a91b..4583b6f 100644 --- a/src/query_engine/AtomDBAPITypes.cc +++ b/src/query_engine/AtomDBAPITypes.cc @@ -1,43 +1,43 @@ +#include "AtomDBAPITypes.h" + #include #include "Utils.h" #include "expression_hasher.h" -#include "AtomDBAPITypes.h" using namespace query_engine; using namespace atomdb_api_types; using namespace commons; -RedisSet::RedisSet(redisReply *reply) : HandleList() { +RedisSet::RedisSet(redisReply* reply) : HandleList() { this->redis_reply = reply; this->handles_size = reply->elements; - this->handles = new char *[this->handles_size]; + this->handles = new char*[this->handles_size]; for (unsigned int i = 0; i < this->handles_size; i++) { handles[i] = reply->element[i]->str; } } RedisSet::~RedisSet() { - delete [] this->handles; + delete[] this->handles; freeReplyObject(this->redis_reply); } -const char *RedisSet::get_handle(unsigned int index) { +const char* RedisSet::get_handle(unsigned int index) { if (index > this->handles_size) { - Utils::error("Handle index out of bounds: " + to_string(index) + " Answer array size: " + to_string(this->handles_size)); + Utils::error("Handle index out of bounds: " + to_string(index) + + " Answer array size: " + to_string(this->handles_size)); } return handles[index]; } -unsigned int RedisSet::size() { - return this->handles_size; -} +unsigned int RedisSet::size() { return this->handles_size; } -RedisStringBundle::RedisStringBundle(redisReply *reply) : HandleList() { +RedisStringBundle::RedisStringBundle(redisReply* reply) : HandleList() { unsigned int handle_length = (HANDLE_HASH_SIZE - 1); this->redis_reply = reply; this->handles_size = reply->len / handle_length; - this->handles = new char *[this->handles_size]; + this->handles = new char*[this->handles_size]; for (unsigned int i = 0; i < this->handles_size; i++) { handles[i] = strndup(reply->str + (i * handle_length), handle_length); } @@ -47,46 +47,51 @@ RedisStringBundle::~RedisStringBundle() { for (unsigned int i = 0; i < this->handles_size; i++) { free(this->handles[i]); } - delete [] this->handles; + delete[] this->handles; freeReplyObject(this->redis_reply); } -const char *RedisStringBundle::get_handle(unsigned int index) { +const char* RedisStringBundle::get_handle(unsigned int index) { if (index > this->handles_size) { - Utils::error("Handle index out of bounds: " + to_string(index) + " Answer handles size: " + to_string(this->handles_size)); + Utils::error("Handle index out of bounds: " + to_string(index) + + " Answer handles size: " + to_string(this->handles_size)); } return handles[index]; } -unsigned int RedisStringBundle::size() { - return this->handles_size; -} +unsigned int RedisStringBundle::size() { return this->handles_size; } MongodbDocument::MongodbDocument(core::v1::optional& document) { this->document = document; } -MongodbDocument::~MongodbDocument() { -} +MongodbDocument::~MongodbDocument() {} -const char *MongodbDocument::get(const string &key) { - // Note for reference: .to_string() instead of .data() would return a std::string +const char* MongodbDocument::get(const string& key) { + // Note for reference: .to_string() instead of .data() would return a + // std::string return ((*this->document)[key]).get_string().value.data(); } -const char *MongodbDocument::get(const string &array_key, unsigned int index) { - // Note for reference: .to_string() instead of .data() would return a std::string +const char* MongodbDocument::get(const string& array_key, unsigned int index) { + // Note for reference: .to_string() instead of .data() would return a + // std::string return ((*this->document)[array_key]).get_array().value[index].get_string().value.data(); } -unsigned int MongodbDocument::get_size(const string &array_key) { - // NOTE TO REVIEWER - // TODO: this implementation is wrong and need to be fixed before integration in das-atom-db - // I couldn't figure out a way to discover the number of elements in a BSON array. - //cout << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << endl; - //cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size()" << endl; - //cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() length: " << ((*this->document)[array_key]).get_array().value.length() << endl; - //cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() HASH: " << HANDLE_HASH_SIZE << endl; - //cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() size: " << ((*this->document)[array_key]).get_array().value.length() / HANDLE_HASH_SIZE << endl; +unsigned int MongodbDocument::get_size(const string& array_key) { + // NOTE TO REVIEWER + // TODO: this implementation is wrong and need to be fixed before integration + // in das-atom-db I couldn't figure out a way to discover the number of + // elements in a BSON array. cout << + // "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + // << endl; cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size()" << endl; + // cout << "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() length: " << + // ((*this->document)[array_key]).get_array().value.length() << endl; cout << + // "XXXXXXXXXXXXXXXXXXX MongodbDocument::get_size() HASH: " << + // HANDLE_HASH_SIZE << endl; cout << "XXXXXXXXXXXXXXXXXXX + // MongodbDocument::get_size() size: " << + // ((*this->document)[array_key]).get_array().value.length() / + // HANDLE_HASH_SIZE << endl; return ((*this->document)[array_key]).get_array().value.length() / HANDLE_HASH_SIZE; } diff --git a/src/query_engine/AtomDBAPITypes.h b/src/query_engine/AtomDBAPITypes.h index 3679508..0dd1a99 100644 --- a/src/query_engine/AtomDBAPITypes.h +++ b/src/query_engine/AtomDBAPITypes.h @@ -2,12 +2,14 @@ #define _QUERY_ENGINE_ATOMDBAPITYPES_H #include + #include #include #include #include #include #include + #include "Utils.h" using namespace std; @@ -16,97 +18,85 @@ using namespace commons; namespace query_engine { namespace atomdb_api_types { - // ------------------------------------------------------------------------------------------------- // NOTE TO REVIEWER: // -// This class will be replaced/integrated by/with classes already implemented in das-atom-db. +// This class will be replaced/integrated by/with classes already implemented in +// das-atom-db. // -// However, that classes will need to be revisited in order to allow the methods implemented here -// because although the design of such methods is nasty, they have the string advantage of -// allowing the reuse of structures allocated by the DBMS (Redis an MongoDB) withpout the need -// of re-allocation of other dataclasses. Although this nasty behavior may not be desirable -// outside the DAS bounds, it's quite appealing inside the query engine (and perhaps other +// However, that classes will need to be revisited in order to allow the methods +// implemented here because although the design of such methods is nasty, they +// have the string advantage of allowing the reuse of structures allocated by +// the DBMS (Redis an MongoDB) withpout the need of re-allocation of other +// dataclasses. Although this nasty behavior may not be desirable outside the +// DAS bounds, it's quite appealing inside the query engine (and perhaps other // parts of internal stuff). // -// I think it's pointless to make any further documentation while we don't make this integrfation. +// I think it's pointless to make any further documentation while we don't make +// this integrfation. // ------------------------------------------------------------------------------------------------- - class HandleList { - -public: - + public: HandleList() {} virtual ~HandleList() {} - virtual const char *get_handle(unsigned int index) = 0; + virtual const char* get_handle(unsigned int index) = 0; virtual unsigned int size() = 0; }; class RedisSet : public HandleList { - -public: - - RedisSet(redisReply *reply); + public: + RedisSet(redisReply* reply); ~RedisSet(); - const char *get_handle(unsigned int index); + const char* get_handle(unsigned int index); unsigned int size(); -private: - + private: unsigned int handles_size; - char **handles; - redisReply *redis_reply; + char** handles; + redisReply* redis_reply; }; class RedisStringBundle : public HandleList { - -public: - - RedisStringBundle(redisReply *reply); + public: + RedisStringBundle(redisReply* reply); ~RedisStringBundle(); - const char *get_handle(unsigned int index); + const char* get_handle(unsigned int index); unsigned int size(); -private: - + private: unsigned int handles_size; - char **handles; - redisReply *redis_reply; + char** handles; + redisReply* redis_reply; }; class AtomDocument { - -public: - + public: AtomDocument() {} virtual ~AtomDocument() {} - virtual const char *get(const string &key) = 0; - virtual const char *get(const string &array_key, unsigned int index) = 0; - virtual unsigned int get_size(const string &array_key) = 0; + virtual const char* get(const string& key) = 0; + virtual const char* get(const string& array_key, unsigned int index) = 0; + virtual unsigned int get_size(const string& array_key) = 0; }; class MongodbDocument : public AtomDocument { - -public: - + public: MongodbDocument(core::v1::optional& document); ~MongodbDocument(); - const char *get(const string &key); - virtual const char *get(const string &array_key, unsigned int index); - virtual unsigned int get_size(const string &array_key); - -private: + const char* get(const string& key); + virtual const char* get(const string& array_key, unsigned int index); + virtual unsigned int get_size(const string& array_key); + private: core::v1::optional document; }; -} // namespace atomdb_api_types -} // namespace query_engine +} // namespace atomdb_api_types +} // namespace query_engine -#endif // _QUERY_ENGINE_ATOMDBAPITYPES_H +#endif // _QUERY_ENGINE_ATOMDBAPITYPES_H diff --git a/src/query_engine/AtomDBSingleton.cc b/src/query_engine/AtomDBSingleton.cc index a037923..4ec0711 100644 --- a/src/query_engine/AtomDBSingleton.cc +++ b/src/query_engine/AtomDBSingleton.cc @@ -1,4 +1,5 @@ #include "AtomDBSingleton.h" + #include "Utils.h" using namespace query_engine; @@ -12,7 +13,9 @@ shared_ptr AtomDBSingleton::atom_db = shared_ptr{}; void AtomDBSingleton::init() { if (initialized) { - Utils::error("AtomDBSingleton already initialized. AtomDBSingleton::init() should be called only once."); + Utils::error( + "AtomDBSingleton already initialized. AtomDBSingleton::init() " + "should be called only once."); } else { AtomDB::initialize_statics(); atom_db = shared_ptr(new AtomDB()); @@ -21,9 +24,12 @@ void AtomDBSingleton::init() { } shared_ptr AtomDBSingleton::get_instance() { - if (! initialized) { - Utils::error("Uninitialized AtomDBSingleton. AtomDBSingleton::init() must be called before AtomDBSingleton::get_instance()"); - return shared_ptr{}; // To avoid warnings + if (!initialized) { + Utils::error( + "Uninitialized AtomDBSingleton. AtomDBSingleton::init() must " + "be called before " + "AtomDBSingleton::get_instance()"); + return shared_ptr{}; // To avoid warnings } else { return atom_db; } diff --git a/src/query_engine/AtomDBSingleton.h b/src/query_engine/AtomDBSingleton.h index 55e4010..52fd743 100644 --- a/src/query_engine/AtomDBSingleton.h +++ b/src/query_engine/AtomDBSingleton.h @@ -2,6 +2,7 @@ #define _QUERY_ENGINE_ATOMDBSINGLETON_H #include + #include "AtomDB.h" using namespace std; @@ -11,26 +12,25 @@ namespace query_engine { // ------------------------------------------------------------------------------------------------- // NOTE TO REVIEWER: // -// This class will be replaced/integrated by/with classes already implemented in das-atom-db. +// This class will be replaced/integrated by/with classes already implemented in +// das-atom-db. // -// I think it's pointless to make any further documentation while we don't make this integrfation. +// I think it's pointless to make any further documentation while we don't make +// this integrfation. // ------------------------------------------------------------------------------------------------- class AtomDBSingleton { - -public: - + public: ~AtomDBSingleton() {} static void init(); static shared_ptr get_instance(); -private: - + private: AtomDBSingleton() {} static bool initialized; static shared_ptr atom_db; }; -} // namespace query_engine +} // namespace query_engine -#endif // _QUERY_ENGINE_ATOMDBSINGLETON_H +#endif // _QUERY_ENGINE_ATOMDBSINGLETON_H diff --git a/src/query_engine/CountAnswer.h b/src/query_engine/CountAnswer.h index 7ae8a44..a7ae909 100644 --- a/src/query_engine/CountAnswer.h +++ b/src/query_engine/CountAnswer.h @@ -13,11 +13,11 @@ namespace query_engine { class CountAnswer : public QueryAnswer { public: - CountAnswer(int count) : count(count) {}; + CountAnswer(int count) : count(count){}; - CountAnswer() : count(UNDEFINED_COUNT) {}; + CountAnswer() : count(UNDEFINED_COUNT){}; - ~CountAnswer() {}; + ~CountAnswer(){}; const string& tokenize() override { this->token_representation = std::to_string(this->count); diff --git a/src/query_engine/DASNode.cc b/src/query_engine/DASNode.cc index c77ca6a..cb1aad3 100644 --- a/src/query_engine/DASNode.cc +++ b/src/query_engine/DASNode.cc @@ -149,7 +149,8 @@ QueryElement* PatternMatchingQuery::build_link_template(vector& tokens, unsigned int arity = std::stoi(tokens[cursor + 2]); if (element_stack.size() < arity) { Utils::error( - "PatternMatchingQuery message: parse error in tokens - too few arguments for LINK_TEMPLATE"); + "PatternMatchingQuery message: parse error in tokens - too " + "few arguments for LINK_TEMPLATE"); } switch (arity) { // TODO: consider replacing each "case" below by a pre-processor macro call @@ -234,7 +235,9 @@ QueryElement* PatternMatchingQuery::build_link_template(vector& tokens, return new LinkTemplate<10>(tokens[cursor + 1], targets, this->context); } default: { - Utils::error("PatternMatchingQuery message: max supported arity for LINK_TEMPLATE: 10"); + Utils::error( + "PatternMatchingQuery message: max supported arity for " + "LINK_TEMPLATE: 10"); } } return NULL; // Just to avoid warnings. This is not actually reachable. @@ -245,7 +248,9 @@ QueryElement* PatternMatchingQuery::build_and(vector& tokens, stack& element_stack) { unsigned int num_clauses = std::stoi(tokens[cursor + 1]); if (element_stack.size() < num_clauses) { - Utils::error("PatternMatchingQuery message: parse error in tokens - too few arguments for AND"); + Utils::error( + "PatternMatchingQuery message: parse error in tokens - too " + "few arguments for AND"); } switch (num_clauses) { // TODO: consider replacing each "case" below by a pre-processor macro call @@ -341,7 +346,9 @@ QueryElement* PatternMatchingQuery::build_or(vector& tokens, stack& element_stack) { unsigned int num_clauses = std::stoi(tokens[cursor + 1]); if (element_stack.size() < num_clauses) { - Utils::error("PatternMatchingQuery message: parse error in tokens - too few arguments for OR"); + Utils::error( + "PatternMatchingQuery message: parse error in tokens - too " + "few arguments for OR"); } switch (num_clauses) { // TODO: consider replacing each "case" below by a pre-processor macro call @@ -437,7 +444,9 @@ QueryElement* PatternMatchingQuery::build_link(vector& tokens, stack& element_stack) { unsigned int arity = std::stoi(tokens[cursor + 2]); if (element_stack.size() < arity) { - Utils::error("PatternMatchingQuery message: parse error in tokens - too few arguments for LINK"); + Utils::error( + "PatternMatchingQuery message: parse error in tokens - too " + "few arguments for LINK"); } switch (arity) { // TODO: consider replacing each "case" below by a pre-processor macro call @@ -578,7 +587,9 @@ PatternMatchingQuery::PatternMatchingQuery(string command, vector& token } if (element_stack.size() != 1) { - Utils::error("PatternMatchingQuery message: parse error in tokens (trailing elements)"); + Utils::error( + "PatternMatchingQuery message: parse error in tokens " + "(trailing elements)"); } this->root_query_element = element_stack.top(); element_stack.pop(); diff --git a/src/query_engine/HandlesAnswer.cc b/src/query_engine/HandlesAnswer.cc index a2a78f6..d3cb93a 100644 --- a/src/query_engine/HandlesAnswer.cc +++ b/src/query_engine/HandlesAnswer.cc @@ -1,23 +1,22 @@ #include "HandlesAnswer.h" -#include "Utils.h" + #include #include #include +#include "Utils.h" + using namespace query_engine; using namespace commons; // ------------------------------------------------------------------------------------------------- // Assignment -Assignment::Assignment() { - this->size = 0; -} +Assignment::Assignment() { this->size = 0; } -Assignment::~Assignment() { -} +Assignment::~Assignment() {} -bool Assignment::assign(const char *label, const char *value) { +bool Assignment::assign(const char* label, const char* value) { for (unsigned int i = 0; i < this->size; i++) { // if label is already present, return true iff its value is the same if (strncmp(label, this->labels[i], MAX_VARIABLE_NAME_SIZE) == 0) { @@ -30,32 +29,33 @@ bool Assignment::assign(const char *label, const char *value) { this->size++; if (this->size == MAX_NUMBER_OF_VARIABLES_IN_QUERY) { Utils::error( - "Assignment size exceeds the maximal number of allowed variables in a query: " + + "Assignment size exceeds the maximal number of allowed " + "variables in a query: " + std::to_string(MAX_NUMBER_OF_VARIABLES_IN_QUERY)); } return true; } -bool Assignment::is_compatible(const Assignment &other) { +bool Assignment::is_compatible(const Assignment& other) { for (unsigned int i = 0; i < this->size; i++) { for (unsigned int j = 0; j < other.size; j++) { if ((strncmp(this->labels[i], other.labels[j], MAX_VARIABLE_NAME_SIZE) == 0) && (strncmp(this->values[i], other.values[j], HANDLE_HASH_SIZE) != 0)) { - return false; + return false; } } } return true; } -void Assignment::copy_from(const Assignment &other) { +void Assignment::copy_from(const Assignment& other) { this->size = other.size; - unsigned int num_bytes = this->size * sizeof(char *); - memcpy((void *) this->labels, (const void *) other.labels, num_bytes); - memcpy((void *) this->values, (const void *) other.values, num_bytes); + unsigned int num_bytes = this->size * sizeof(char*); + memcpy((void*) this->labels, (const void*) other.labels, num_bytes); + memcpy((void*) this->values, (const void*) other.values, num_bytes); } -void Assignment::add_assignments(const Assignment &other) { +void Assignment::add_assignments(const Assignment& other) { bool already_contains; for (unsigned int j = 0; j < other.size; j++) { already_contains = false; @@ -65,7 +65,7 @@ void Assignment::add_assignments(const Assignment &other) { break; } } - if (! already_contains) { + if (!already_contains) { this->labels[this->size] = other.labels[j]; this->values[this->size] = other.values[j]; this->size++; @@ -73,7 +73,7 @@ void Assignment::add_assignments(const Assignment &other) { } } -const char *Assignment::get(const char *label) { +const char* Assignment::get(const char* label) { for (unsigned int i = 0; i < this->size; i++) { if (strncmp(label, this->labels[i], MAX_VARIABLE_NAME_SIZE) == 0) { return this->values[i]; @@ -82,9 +82,7 @@ const char *Assignment::get(const char *label) { return NULL; } -unsigned int Assignment::variable_count() { - return this->size; -} +unsigned int Assignment::variable_count() { return this->size; } string Assignment::to_string() { string answer = "{"; @@ -101,40 +99,32 @@ string Assignment::to_string() { // ------------------------------------------------------------------------------------------------- // HandlesAnswer - -HandlesAnswer::HandlesAnswer() : HandlesAnswer(0.0) { -} +HandlesAnswer::HandlesAnswer() : HandlesAnswer(0.0) {} HandlesAnswer::HandlesAnswer(double importance) { this->importance = importance; this->handles_size = 0; } -HandlesAnswer::HandlesAnswer(const char *handle, double importance) { +HandlesAnswer::HandlesAnswer(const char* handle, double importance) { this->importance = importance; this->handles[0] = handle; this->handles_size = 1; } -HandlesAnswer::~HandlesAnswer() { -} +HandlesAnswer::~HandlesAnswer() {} -void HandlesAnswer::add_handle(const char *handle) { - this->handles[this->handles_size++] = handle; -} +void HandlesAnswer::add_handle(const char* handle) { this->handles[this->handles_size++] = handle; } -HandlesAnswer *HandlesAnswer::copy(HandlesAnswer *base) { // Static method - HandlesAnswer *copy = new HandlesAnswer(base->importance); +HandlesAnswer* HandlesAnswer::copy(HandlesAnswer* base) { // Static method + HandlesAnswer* copy = new HandlesAnswer(base->importance); copy->assignment.copy_from(base->assignment); copy->handles_size = base->handles_size; - memcpy( - (void *) copy->handles, - (const void *) base->handles, - base->handles_size * sizeof(char *)); + memcpy((void*) copy->handles, (const void*) base->handles, base->handles_size * sizeof(char*)); return copy; } -bool HandlesAnswer::merge(HandlesAnswer *other, bool merge_handles) { +bool HandlesAnswer::merge(HandlesAnswer* other, bool merge_handles) { if (this->assignment.is_compatible(other->assignment)) { this->assignment.add_assignments(other->assignment); bool already_exist; @@ -148,7 +138,7 @@ bool HandlesAnswer::merge(HandlesAnswer *other, bool merge_handles) { break; } } - if (! already_exist) { + if (!already_exist) { this->handles[this->handles_size++] = other->handles[j]; } } @@ -169,21 +159,21 @@ string HandlesAnswer::to_string() { } } answer += "] " + this->assignment.to_string() + " " + std::to_string(this->importance); - //answer += "] " + this->assignment.to_string(); + // answer += "] " + this->assignment.to_string(); return answer; } -const string &HandlesAnswer::tokenize() { - // char_count is computed to be slightly larger than actually required by assuming - // e.g. 3 digits to represent sizes +const string& HandlesAnswer::tokenize() { + // char_count is computed to be slightly larger than actually required by + // assuming e.g. 3 digits to represent sizes char importance_buffer[13]; sprintf(importance_buffer, "%.10f", this->importance); - unsigned int char_count = - 13 // importance with 10 decimals + space - + 4 // (up to 3 digits) to represent this->handles_size + space - + this->handles_size * (HANDLE_HASH_SIZE + 1) // handles + spaces - + 4 // (up to 3 digits) to represent this->assignment.size + space - + this->assignment.size * (MAX_VARIABLE_NAME_SIZE + HANDLE_HASH_SIZE + 2); // labelhandle + unsigned int char_count = 13 // importance with 10 decimals + space + + 4 // (up to 3 digits) to represent this->handles_size + space + + this->handles_size * (HANDLE_HASH_SIZE + 1) // handles + spaces + + 4 // (up to 3 digits) to represent this->assignment.size + space + + this->assignment.size * (MAX_VARIABLE_NAME_SIZE + HANDLE_HASH_SIZE + + 2); // labelhandle this->token_representation.clear(); this->token_representation.reserve(char_count); @@ -208,12 +198,10 @@ const string &HandlesAnswer::tokenize() { return this->token_representation; } -static inline void read_token( - const char *token_string, - unsigned int &cursor, - char *token, - unsigned int token_size) { - +static inline void read_token(const char* token_string, + unsigned int& cursor, + char* token, + unsigned int token_size) { unsigned int cursor_token = 0; while (token_string[cursor] != ' ') { if ((cursor_token == token_size) || (token_string[cursor] == '\0')) { @@ -225,9 +213,8 @@ static inline void read_token( cursor++; } -void HandlesAnswer::untokenize(const string &tokens) { - - const char *token_string = tokens.c_str(); +void HandlesAnswer::untokenize(const string& tokens) { + const char* token_string = tokens.c_str(); char number[4]; char importance[13]; char handle[HANDLE_HASH_SIZE]; @@ -241,7 +228,8 @@ void HandlesAnswer::untokenize(const string &tokens) { read_token(token_string, cursor, number, 4); this->handles_size = (unsigned int) std::stoi(number); if (this->handles_size > MAX_NUMBER_OF_OPERATION_CLAUSES) { - Utils::error("Invalid handles_size: " + std::to_string(this->handles_size) + " untokenizing HandlesAnswer"); + Utils::error("Invalid handles_size: " + std::to_string(this->handles_size) + + " untokenizing HandlesAnswer"); } for (unsigned int i = 0; i < this->handles_size; i++) { @@ -253,7 +241,8 @@ void HandlesAnswer::untokenize(const string &tokens) { this->assignment.size = (unsigned int) std::stoi(number); if (this->assignment.size > MAX_NUMBER_OF_VARIABLES_IN_QUERY) { - Utils::error("Invalid number of assignments: " + std::to_string(this->assignment.size) + " untokenizing HandlesAnswer"); + Utils::error("Invalid number of assignments: " + std::to_string(this->assignment.size) + + " untokenizing HandlesAnswer"); } for (unsigned int i = 0; i < this->assignment.size; i++) { diff --git a/src/query_engine/HandlesAnswer.h b/src/query_engine/HandlesAnswer.h index 2fb0534..c81a3be 100644 --- a/src/query_engine/HandlesAnswer.h +++ b/src/query_engine/HandlesAnswer.h @@ -2,16 +2,18 @@ #define _QUERY_ENGINE_HANDLESANSWER_H #include -#include "expression_hasher.h" + #include "QueryAnswer.h" +#include "expression_hasher.h" using namespace std; namespace query_engine { /** - * This class is the representation of a set of variable assignments. It's a set because each - * variable can be assigned to exactly one value and the order of assignments is irrelevant. + * This class is the representation of a set of variable assignments. It's a set + * because each variable can be assigned to exactly one value and the order of + * assignments is irrelevant. * * "label1" -> "value1" * "label2" -> "value2" @@ -19,116 +21,120 @@ namespace query_engine { * "labelN" -> "valueN" */ class Assignment { - friend class HandlesAnswer; - public: - - /** - * Basic constructor. - */ - Assignment(); - - /** - * Destructor. - */ - ~Assignment(); - - /** - * Assign a value to a label. - * - * If the label have already an assigned value, assign() will check if the value is the - * same. If not, nothing is done and false is returned. If the value is the same, or - * if the label haven't been assigned yet, true is returned. - * - * @param label Label - * @param value Value to be assigned to the passed label. - * @return true iff the label have no value assigned to it or if the passed value is - * the same as the currently assigned value. - */ - bool assign(const char *label, const char *value); - - /** - * Returns the value assigned to a given label or NULL if no value is assigned to it. - * - * @param label Label to be search for. - * @return The value assigned to a given label or NULL if no value is assigned to it. - */ - const char *get(const char *label); - - /** - * Returns true if the passed Assignment is compatible with this one or false otherwise. - * - * For two Assignments to be considered compatible, all the labels they share must be - * assigned to the same value. Labels defined in only one of the Assignments aren't - * taken into account (so assignments with no common labels will always be compatible). - * - * Empty Assignments are compatible with any other Assignment. - */ - bool is_compatible(const Assignment &other); - - /** - * Shallow copy operation. No allocation of labels or values are performed. - * - * @param other Assignment to be copied from. - */ - void copy_from(const Assignment &other); - - /** - * Adds assignments from other Assignment by making a shallow copy of labels and values. - * - * Labels present in both Assignments are disregarded. So, for instance, if 'this' has: - * - * "label1"-> "value1" - * "label2"-> "value2" - * "label3"-> "value3" - * - * and 'other' has: - * - * "label1"-> "valueX" - * "label2"-> "value2" - * "label4"-> "value4" - * - * The result in 'this' after add_assignment() would be: - * - * "label1"-> "value1" - * "label2"-> "value2" - * "label3"-> "value3" - * "label4"-> "value4" - */ - void add_assignments(const Assignment &other); - - /** - * Returns the number of labels in this assignment. - * - * @return The number of labels in this assignment. - */ - unsigned int variable_count(); - - /** - * Returns a string representation of this Node (mainly for debugging; not optimized to - * production environment). - */ - string to_string(); - - private: - - const char *labels[MAX_NUMBER_OF_VARIABLES_IN_QUERY]; - const char *values[MAX_NUMBER_OF_VARIABLES_IN_QUERY]; - unsigned int size; + public: + /** + * Basic constructor. + */ + Assignment(); + + /** + * Destructor. + */ + ~Assignment(); + + /** + * Assign a value to a label. + * + * If the label have already an assigned value, assign() will check if the + * value is the same. If not, nothing is done and false is returned. If the + * value is the same, or if the label haven't been assigned yet, true is + * returned. + * + * @param label Label + * @param value Value to be assigned to the passed label. + * @return true iff the label have no value assigned to it or if the passed + * value is the same as the currently assigned value. + */ + bool assign(const char* label, const char* value); + + /** + * Returns the value assigned to a given label or NULL if no value is assigned + * to it. + * + * @param label Label to be search for. + * @return The value assigned to a given label or NULL if no value is assigned + * to it. + */ + const char* get(const char* label); + + /** + * Returns true if the passed Assignment is compatible with this one or false + * otherwise. + * + * For two Assignments to be considered compatible, all the labels they share + * must be assigned to the same value. Labels defined in only one of the + * Assignments aren't taken into account (so assignments with no common labels + * will always be compatible). + * + * Empty Assignments are compatible with any other Assignment. + */ + bool is_compatible(const Assignment& other); + + /** + * Shallow copy operation. No allocation of labels or values are performed. + * + * @param other Assignment to be copied from. + */ + void copy_from(const Assignment& other); + + /** + * Adds assignments from other Assignment by making a shallow copy of labels + * and values. + * + * Labels present in both Assignments are disregarded. So, for instance, if + * 'this' has: + * + * "label1"-> "value1" + * "label2"-> "value2" + * "label3"-> "value3" + * + * and 'other' has: + * + * "label1"-> "valueX" + * "label2"-> "value2" + * "label4"-> "value4" + * + * The result in 'this' after add_assignment() would be: + * + * "label1"-> "value1" + * "label2"-> "value2" + * "label3"-> "value3" + * "label4"-> "value4" + */ + void add_assignments(const Assignment& other); + + /** + * Returns the number of labels in this assignment. + * + * @return The number of labels in this assignment. + */ + unsigned int variable_count(); + + /** + * Returns a string representation of this Node (mainly for debugging; not + * optimized to production environment). + */ + string to_string(); + + private: + const char* labels[MAX_NUMBER_OF_VARIABLES_IN_QUERY]; + const char* values[MAX_NUMBER_OF_VARIABLES_IN_QUERY]; + unsigned int size; }; /** - * This is a candidate answer for a query. + * This is a candidate answer for a query. * - * Objects of this class are moved through the flow of answers in the query tree. - * They have a set of handles, an Assignment and an attached importance value which - * is calculated using the importance of the elements which have been operated to - * make the answer. + * Objects of this class are moved through the flow of answers in the query + * tree. They have a set of handles, an Assignment and an attached importance + * value which is calculated using the importance of the elements which have + * been operated to make the answer. * - * The set of handles represents Links that, together, represent a candidate answer - * to the query, under the constraints of the attached assignment of variables. For instance, - * suppose we have a query like: + * The set of handles represents Links that, together, represent a candidate + * answer to the query, under the constraints of the attached assignment of + * variables. For instance, suppose we have a query like: * * AND * Inheritance @@ -147,13 +153,11 @@ class Assignment { * $v1 -> S */ class HandlesAnswer : public QueryAnswer { - -public: - + public: /** * Handles which are the constituents of this HandlesAnswer. */ - const char *handles[MAX_NUMBER_OF_OPERATION_CLAUSES]; + const char* handles[MAX_NUMBER_OF_OPERATION_CLAUSES]; /** * Number of handles in this HandlesAnswer. @@ -161,7 +165,8 @@ class HandlesAnswer : public QueryAnswer { unsigned int handles_size; /** - * Estimated importance of this HandlesAnswer based on the importance of its constituents. + * Estimated importance of this HandlesAnswer based on the importance of its + * constituents. */ double importance; @@ -176,7 +181,7 @@ class HandlesAnswer : public QueryAnswer { * @param handle First handle in this HandlesAnswer. * @param importance Estimated importance of this HandlesAnswer. */ - HandlesAnswer(const char *handle, double importance); + HandlesAnswer(const char* handle, double importance); /** * Constructor. @@ -200,63 +205,66 @@ class HandlesAnswer : public QueryAnswer { * * @param handles Handle to be added to this HandlesAnswer. */ - void add_handle(const char *handle); + void add_handle(const char* handle); /** * Merges this HandlesAnswer with the passed one. * * @param other HandlesAnswer to be merged in this one. - * @param merge_handles A flag (defaulted to true) to indicate whether the handles should be - * merged (in addition to the assignments). + * @param merge_handles A flag (defaulted to true) to indicate whether the + * handles should be merged (in addition to the assignments). */ - bool merge(HandlesAnswer *other, bool merge_handles = true); + bool merge(HandlesAnswer* other, bool merge_handles = true); /** * Make a shallow copy of the passed HandlesAnswer. * - * A new HandlesAnswer object is allocated but the assignment and the handles are shallow-copied. + * A new HandlesAnswer object is allocated but the assignment and the handles + * are shallow-copied. */ - static HandlesAnswer *copy(HandlesAnswer *base); + static HandlesAnswer* copy(HandlesAnswer* base); /** - * Tokenizes the HandlesAnswer in a single std::string object (tokens separated by spaces). + * Tokenizes the HandlesAnswer in a single std::string object (tokens + * separated by spaces). * * The tokenized string looks like this: * * N H1 H2 ... HN M L1 V1 L2 V2 ... LM VM * - * N is the number of handles in the HandlesAnswer and M is the number of assignments. Hi are the - * handles and Li Vi are the assignments Li -> Vi + * N is the number of handles in the HandlesAnswer and M is the number of + * assignments. Hi are the handles and Li Vi are the assignments Li -> Vi * - * @return A std::string with tokens separated by spaces which can be used to rebuild this HandlesAnswer. + * @return A std::string with tokens separated by spaces which can be used to + * rebuild this HandlesAnswer. */ const string& tokenize() override; /** - * Rebuild a HandlesAnswer baesd in a list of tokens given in a std::string with tokens separated by spaces. + * Rebuild a HandlesAnswer baesd in a list of tokens given in a std::string + * with tokens separated by spaces. * * The tokenized string looks like this: * * N H1 H2 ... HN M L1 V1 L2 V2 ... LM VM * - * N is the number of handles in the HandlesAnswer and M is the number of assignments. Hi are the - * handles and Li Vi are the assignments Li -> Vi + * N is the number of handles in the HandlesAnswer and M is the number of + * assignments. Hi are the handles and Li Vi are the assignments Li -> Vi * * @param tokens A std::string with the list of tokens separated by spaces. */ - void untokenize(const string &tokens) override; + void untokenize(const string& tokens) override; /** - * Returns a string representation of this Variable (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Variable (mainly for debugging; not + * optimized to production environment). */ string to_string() override; -private: - + private: string token_representation; }; -} // namespace query_engine +} // namespace query_engine -#endif // _QUERY_ENGINE_HANDLESANSWER_H +#endif // _QUERY_ENGINE_HANDLESANSWER_H diff --git a/src/query_engine/StarNode.cc b/src/query_engine/StarNode.cc index 0dc3d18..e56f645 100644 --- a/src/query_engine/StarNode.cc +++ b/src/query_engine/StarNode.cc @@ -1,4 +1,5 @@ #include "StarNode.h" + #include "LeadershipBroker.h" #include "MessageBroker.h" @@ -8,34 +9,26 @@ using namespace std; // ------------------------------------------------------------------------------------------------- // Constructors and destructors -StarNode::StarNode( - const string &node_id, - MessageBrokerType messaging_backend) : - DistributedAlgorithmNode(node_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_backend) { - +StarNode::StarNode(const string& node_id, MessageBrokerType messaging_backend) + : DistributedAlgorithmNode(node_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_backend) { this->is_server = true; this->join_network(); } -StarNode::StarNode( - const string &node_id, - const string &server_id, - MessageBrokerType messaging_backend) : - DistributedAlgorithmNode(node_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_backend) { - +StarNode::StarNode(const string& node_id, const string& server_id, MessageBrokerType messaging_backend) + : DistributedAlgorithmNode(node_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_backend) { this->server_id = server_id; this->is_server = false; this->add_peer(server_id); this->join_network(); } -StarNode::~StarNode() { -} +StarNode::~StarNode() {} // ------------------------------------------------------------------------------------------------- // DistributedAlgorithmNode virtual API -void StarNode::node_joined_network(const string &node_id) { +void StarNode::node_joined_network(const string& node_id) { if (this->is_server) { this->add_peer(node_id); } diff --git a/src/query_engine/StarNode.h b/src/query_engine/StarNode.h index b43ac2d..8fae35e 100644 --- a/src/query_engine/StarNode.h +++ b/src/query_engine/StarNode.h @@ -2,6 +2,7 @@ #define _QUERY_NODE_STARNODE_H #include + #include "DistributedAlgorithmNode.h" using namespace std; @@ -9,15 +10,13 @@ using namespace std; namespace distributed_algorithm_node { /** - * Node in a "star" topology with one single server (which knows every other nodes in the network) - * and N nodes (which know only the server). + * Node in a "star" topology with one single server (which knows every other + * nodes in the network) and N nodes (which know only the server). * * Use the different constructors to choose from client or server. */ class StarNode : public DistributedAlgorithmNode { - -public: - + public: // -------------------------------------------------------------------------------------------- // Constructors and destructors @@ -25,25 +24,22 @@ class StarNode : public DistributedAlgorithmNode { * Server constructor. * * @param node_id ID of this node in the network. - * @param messaging_backend Type of network communication which will be used by the nodes. - * in the network to exchange messages. Defaulted to GRPC. + * @param messaging_backend Type of network communication which will be used + * by the nodes. in the network to exchange messages. Defaulted to GRPC. */ - StarNode( - const string &node_id, - MessageBrokerType messaging_backend = MessageBrokerType::GRPC); + StarNode(const string& node_id, MessageBrokerType messaging_backend = MessageBrokerType::GRPC); /** * Client constructor. * * @param node_id ID of this node in the network. * @param server_id ID of the server node. - * @param messaging_backend Type of network communication which will be used by the nodes - * in the network to exchange messages. Defaulted to GRPC. + * @param messaging_backend Type of network communication which will be used + * by the nodes in the network to exchange messages. Defaulted to GRPC. */ - StarNode( - const string &node_id, - const string &server_id, - MessageBrokerType messaging_backend = MessageBrokerType::GRPC); + StarNode(const string& node_id, + const string& server_id, + MessageBrokerType messaging_backend = MessageBrokerType::GRPC); /** * Destructor @@ -54,26 +50,27 @@ class StarNode : public DistributedAlgorithmNode { // DistributedAlgorithmNode virtual API /** - * Method called when a new node is inserted in the network after this one has already joined. - * Server nodes will keep track of all newly inserted nodes. Client nodes disregard the info. + * Method called when a new node is inserted in the network after this one has + * already joined. Server nodes will keep track of all newly inserted nodes. + * Client nodes disregard the info. * * @param node_id ID of the newly inserted node. */ - void node_joined_network(const string &node_id); + void node_joined_network(const string& node_id); /** * Method called when a leadershipo election is requested. * - * Server nodes votes in themselves for leader while client node votes in their server. + * Server nodes votes in themselves for leader while client node votes in + * their server. */ string cast_leadership_vote(); -protected: - + protected: bool is_server; string server_id; }; -} // namespace distributed_algorithm_node +} // namespace distributed_algorithm_node -#endif // _QUERY_NODE_STARNODE_H +#endif // _QUERY_NODE_STARNODE_H diff --git a/src/query_engine/answer_processor/AttentionBrokerUpdater.h b/src/query_engine/answer_processor/AttentionBrokerUpdater.h index e580a08..bdecfc8 100644 --- a/src/query_engine/answer_processor/AttentionBrokerUpdater.h +++ b/src/query_engine/answer_processor/AttentionBrokerUpdater.h @@ -57,8 +57,8 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { // Protobuf data structures dasproto::HandleList* handle_list; // will contain single_answer (can't be used directly // because it's a list, not a set. - dasproto::HandleCount handle_count; // Counting of how many times each handle appeared - // in all single_entry + dasproto::HandleCount handle_count; // Counting of how many times each + // handle appeared in all single_entry dasproto::Ack* ack; // Command return shared_ptr db = AtomDBSingleton::get_instance(); @@ -88,7 +88,8 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { #ifdef DEBUG count_total_processed++; if ((count_total_processed % 1000) == 0) { - cout << "RemoteSink::attention_broker_postprocess_method() count_total_processed: " + cout << "RemoteSink::attention_broker_postprocess_method() " + "count_total_processed: " << count_total_processed << endl; } #endif @@ -130,8 +131,8 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { single_answer.clear(); ack = new dasproto::Ack(); #ifdef DEBUG - // cout << "RemoteSink::attention_broker_postprocess_method() requesting CORRELATE" << - // endl; + // cout << "RemoteSink::attention_broker_postprocess_method() requesting + // CORRELATE" << endl; #endif stub->correlate(new grpc::ClientContext(), *handle_list, ack); if (ack->msg() != "CORRELATE") { @@ -149,7 +150,8 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { auto stub = dasproto::AttentionBroker::NewStub(grpc::CreateChannel( this->attention_broker_address, grpc::InsecureChannelCredentials())); #ifdef DEBUG - cout << "RemoteSink::attention_broker_postprocess_method() requesting STIMULATE" + cout << "RemoteSink::attention_broker_postprocess_method() " + "requesting STIMULATE" << endl; #endif handle_count.set_context(this->query_context); @@ -177,7 +179,9 @@ class AttentionBrokerUpdater : public QueryAnswerProcessor { auto stub = dasproto::AttentionBroker::NewStub( grpc::CreateChannel(this->attention_broker_address, grpc::InsecureChannelCredentials())); #ifdef DEBUG - cout << "RemoteSink::attention_broker_postprocess_method() requesting STIMULATE" << endl; + cout << "RemoteSink::attention_broker_postprocess_method() requesting " + "STIMULATE" + << endl; #endif handle_count.set_context(this->query_context); stub->stimulate(new grpc::ClientContext(), handle_count, ack); diff --git a/src/query_engine/query_element/And.h b/src/query_engine/query_element/And.h index ebc9bc6..5143b51 100644 --- a/src/query_engine/query_element/And.h +++ b/src/query_engine/query_element/And.h @@ -1,53 +1,50 @@ #ifndef _QUERY_ELEMENT_AND_H #define _QUERY_ELEMENT_AND_H -#include #include -#include "Operator.h" +#include + #include "HandlesAnswer.h" +#include "Operator.h" using namespace std; namespace query_element { - /** * QueryElement representing an AND logic operator. * - * And operates on N clauses. Each clause can be either a Source or another Operator. + * And operates on N clauses. Each clause can be either a Source or another + * Operator. */ template class And : public Operator { - -public: - + public: // -------------------------------------------------------------------------------------------- // Constructors and destructors /** * Constructor. * - * @param clauses Array with N clauses (each clause is supposed to be a Source or an Operator). + * @param clauses Array with N clauses (each clause is supposed to be a Source + * or an Operator). */ - And(QueryElement **clauses) : Operator(clauses) { - initialize(clauses); - } + And(QueryElement** clauses) : Operator(clauses) { initialize(clauses); } /** * Constructor. * - * @param clauses Array with N clauses (each clause is supposed to be a Source or an Operator). + * @param clauses Array with N clauses (each clause is supposed to be a Source + * or an Operator). */ - And(const array &clauses) : Operator(clauses) { - initialize((QueryElement **) clauses.data()); + And(const array& clauses) : Operator(clauses) { + initialize((QueryElement**) clauses.data()); } /** * Destructor. */ - ~And() { - graceful_shutdown(); - } + ~And() { graceful_shutdown(); } // -------------------------------------------------------------------------------------------- // QueryElement API @@ -64,43 +61,31 @@ class And : public Operator { this->operator_thread = NULL; } } - + // -------------------------------------------------------------------------------------------- // Private stuff -private: - + private: class CandidateRecord { - public: - HandlesAnswer *answer[N]; + public: + HandlesAnswer* answer[N]; unsigned int index[N]; double fitness; - CandidateRecord() { - } - CandidateRecord(const CandidateRecord &other) { + CandidateRecord() {} + CandidateRecord(const CandidateRecord& other) { this->fitness = other.fitness; - memcpy((void *) this->index, (const void *) other.index, N * sizeof(unsigned int)); - memcpy( - (void *) this->answer, - (const void *) other.answer, - N * sizeof(HandlesAnswer *)); + memcpy((void*) this->index, (const void*) other.index, N * sizeof(unsigned int)); + memcpy((void*) this->answer, (const void*) other.answer, N * sizeof(HandlesAnswer*)); } - CandidateRecord& operator=(const CandidateRecord &other) { + CandidateRecord& operator=(const CandidateRecord& other) { this->fitness = other.fitness; - memcpy((void *) this->index, (const void *) other.index, N * sizeof(unsigned int)); - memcpy( - (void *) this->answer, - (const void *) other.answer, - N * sizeof(HandlesAnswer *)); + memcpy((void*) this->index, (const void*) other.index, N * sizeof(unsigned int)); + memcpy((void*) this->answer, (const void*) other.answer, N * sizeof(HandlesAnswer*)); return *this; } - bool operator<(const CandidateRecord &other) const { - return this->fitness < other.fitness; - } - bool operator>(const CandidateRecord &other) const { - return this->fitness > other.fitness; - } - bool operator==(const CandidateRecord &other) const { + bool operator<(const CandidateRecord& other) const { return this->fitness < other.fitness; } + bool operator>(const CandidateRecord& other) const { return this->fitness > other.fitness; } + bool operator==(const CandidateRecord& other) const { for (unsigned int i = 0; i < N; i++) { if (this->index[i] != other.index[i]) { return false; @@ -120,17 +105,17 @@ class And : public Operator { } return hash; } - }; + }; - vector query_answer[N]; + vector query_answer[N]; unsigned int next_input_to_process[N]; priority_queue border; unordered_set visited; bool all_answers_arrived[N]; bool no_more_answers_to_arrive; - thread *operator_thread; + thread* operator_thread; - void initialize(QueryElement **clauses) { + void initialize(QueryElement** clauses) { this->operator_thread = NULL; for (unsigned int i = 0; i < N; i++) { this->next_input_to_process[i] = 0; @@ -149,7 +134,7 @@ class And : public Operator { bool ready_to_process_candidate() { for (unsigned int i = 0; i < N; i++) { - if ((! this->all_answers_arrived[i]) && + if ((!this->all_answers_arrived[i]) && (this->query_answer[i].size() <= (this->next_input_to_process[i] + 1))) { return false; } @@ -161,17 +146,17 @@ class And : public Operator { if (this->no_more_answers_to_arrive) { return; } - HandlesAnswer *answer; + HandlesAnswer* answer; unsigned int all_arrived_count = 0; bool no_new_answer = true; for (unsigned int i = 0; i < N; i++) { - while ((answer = dynamic_cast(this->input_buffer[i]->pop_query_answer())) != NULL) { + while ((answer = dynamic_cast(this->input_buffer[i]->pop_query_answer())) != + NULL) { no_new_answer = false; this->query_answer[i].push_back(answer); } if (this->input_buffer[i]->is_query_answers_empty() && this->input_buffer[i]->is_query_answers_finished()) { - this->all_answers_arrived[i] = true; all_arrived_count++; } @@ -185,10 +170,10 @@ class And : public Operator { } } - void operate_candidate(const CandidateRecord &candidate) { - HandlesAnswer *new_query_answer = HandlesAnswer::copy(candidate.answer[0]); + void operate_candidate(const CandidateRecord& candidate) { + HandlesAnswer* new_query_answer = HandlesAnswer::copy(candidate.answer[0]); for (unsigned int i = 1; i < N; i++) { - if (! new_query_answer->merge(candidate.answer[i])) { + if (!new_query_answer->merge(candidate.answer[i])) { delete new_query_answer; return; } @@ -209,7 +194,7 @@ class And : public Operator { return true; } - void expand_border(const CandidateRecord &last_used_candidate) { + void expand_border(const CandidateRecord& last_used_candidate) { CandidateRecord candidate; unsigned int index_in_queue; bool abort_candidate; @@ -229,7 +214,7 @@ class And : public Operator { break; } } - candidate.answer[answer_queue_index] = + candidate.answer[answer_queue_index] = this->query_answer[answer_queue_index][index_in_queue]; candidate.index[answer_queue_index] = index_in_queue; candidate.fitness *= candidate.answer[answer_queue_index]->importance; @@ -245,11 +230,8 @@ class And : public Operator { } void and_operator_method() { - do { - if (QueryElement::is_flow_finished() || - this->output_buffer->is_query_answers_finished()) { - + if (QueryElement::is_flow_finished() || this->output_buffer->is_query_answers_finished()) { return; } @@ -258,19 +240,19 @@ class And : public Operator { return; } ingest_newly_arrived_answers(); - } while (! ready_to_process_candidate()); + } while (!ready_to_process_candidate()); if (processed_all_input()) { bool all_finished_flag = true; for (unsigned int i = 0; i < N; i++) { - if (! this->input_buffer[i]->is_query_answers_finished()) { + if (!this->input_buffer[i]->is_query_answers_finished()) { all_finished_flag = false; break; } } - if (all_finished_flag && - ! this->output_buffer->is_query_answers_finished() && - // processed_all_input() is double-checked on purpose to avoid race condition + if (all_finished_flag && !this->output_buffer->is_query_answers_finished() && + // processed_all_input() is double-checked on purpose to avoid race + // condition processed_all_input()) { this->output_buffer->query_answers_finished(); } @@ -299,6 +281,6 @@ class And : public Operator { } }; -} // namespace query_element +} // namespace query_element -#endif // _QUERY_ELEMENT_AND_H +#endif // _QUERY_ELEMENT_AND_H diff --git a/src/query_engine/query_element/Iterator.cc b/src/query_engine/query_element/Iterator.cc index 67f0b60..4b221d0 100644 --- a/src/query_engine/query_element/Iterator.cc +++ b/src/query_engine/query_element/Iterator.cc @@ -7,26 +7,21 @@ using namespace query_element; // ------------------------------------------------------------------------------------------------- // Public methods -template -Iterator::Iterator( - QueryElement *precedent, - bool delete_precedent_on_destructor) : - Sink(precedent, "Iterator(" + precedent->id + ")", delete_precedent_on_destructor) { -} +template +Iterator::Iterator(QueryElement* precedent, bool delete_precedent_on_destructor) + : Sink(precedent, "Iterator(" + precedent->id + ")", delete_precedent_on_destructor) {} -template -Iterator::~Iterator() { -} +template +Iterator::~Iterator() {} -template +template bool Iterator::finished() { // The order of the AND clauses below matters - return ( - this->input_buffer->is_query_answers_finished() && - this->input_buffer->is_query_answers_empty()); + return (this->input_buffer->is_query_answers_finished() && + this->input_buffer->is_query_answers_empty()); } -template -QueryAnswer *Iterator::pop() { - return (QueryAnswer *) this->input_buffer->pop_query_answer(); +template +QueryAnswer* Iterator::pop() { + return (QueryAnswer*) this->input_buffer->pop_query_answer(); } diff --git a/src/query_engine/query_element/Iterator.h b/src/query_engine/query_element/Iterator.h index d29ef57..a96340a 100644 --- a/src/query_engine/query_element/Iterator.h +++ b/src/query_engine/query_element/Iterator.h @@ -1,8 +1,8 @@ #ifndef _QUERY_ELEMENT_ITERATOR_H #define _QUERY_ELEMENT_ITERATOR_H -#include "Sink.h" #include "QueryAnswer.h" +#include "Sink.h" using namespace std; using namespace query_engine; @@ -10,7 +10,8 @@ using namespace query_engine; namespace query_element { /** - * Concrete Sink that provides an iterator API to give access to the query answers. + * Concrete Sink that provides an iterator API to give access to the query + * answers. * * NB This is not a std::iterator as the behavior we'd expect of a std::iterator * doesn't fit well with the asynchronous nature of QueryElement processing. @@ -21,41 +22,42 @@ namespace query_element { */ template class Iterator : public Sink { - -public: - + public: /** - * Constructor expects that the QueryElement below in the tree is already constructed. + * Constructor expects that the QueryElement below in the tree is already + * constructed. */ - Iterator(QueryElement *precedent, bool delete_precedent_on_destructor = false); + Iterator(QueryElement* precedent, bool delete_precedent_on_destructor = false); ~Iterator(); // -------------------------------------------------------------------------------------------- // Public Iterator API /** - * Return true when all query answers has been processed AND all the query answers - * that reached this QueryElement has been pop'ed out using the method pop(). + * Return true when all query answers has been processed AND all the query + * answers that reached this QueryElement has been pop'ed out using the method + * pop(). * - * @return true iff all query answers has been processed AND all the query answers - * that reached this QueryElement has been pop'ed out using the method pop(). + * @return true iff all query answers has been processed AND all the query + * answers that reached this QueryElement has been pop'ed out using the method + * pop(). */ bool finished(); /** * Return the next query answer or NULL if none are currently available. * - * NB a NULL return DOESN'T mean that the query answers are over. It means that there - * are no query answers available now. Because of the asynchronous nature of QueryElement - * processing, more query answers can arrive later. + * NB a NULL return DOESN'T mean that the query answers are over. It means + * that there are no query answers available now. Because of the asynchronous + * nature of QueryElement processing, more query answers can arrive later. * * @return the next query answer or NULL if none are currently available. */ - QueryAnswer *pop(); + QueryAnswer* pop(); }; -} // namespace query_element +} // namespace query_element #include "Iterator.cc" -#endif // _QUERY_ELEMENT_ITERATOR_H +#endif // _QUERY_ELEMENT_ITERATOR_H diff --git a/src/query_engine/query_element/LinkTemplate.h b/src/query_engine/query_element/LinkTemplate.h index f092811..87b65a2 100644 --- a/src/query_engine/query_element/LinkTemplate.h +++ b/src/query_engine/query_element/LinkTemplate.h @@ -28,8 +28,8 @@ using namespace attention_broker_server; namespace query_element { /** - * Concrete Source that searches for a pattern in the AtomDB and feeds the QueryElement up in the - * query tree with the resulting links. + * Concrete Source that searches for a pattern in the AtomDB and feeds the + * QueryElement up in the query tree with the resulting links. * * A pattern is something like: * @@ -37,12 +37,14 @@ namespace query_element { * Human * $v1 * - * In the example, any links of type "Similarity" pointing to Human as the first target would be - * returned. These returned links are then fed into the subsequent QueryElement in the tree. + * In the example, any links of type "Similarity" pointing to Human as the first + * target would be returned. These returned links are then fed into the + * subsequent QueryElement in the tree. * - * LinkTemplate query the AtomDB for the links that match the pattern. In addition to this, it - * attaches values for any variables in the pattern and sorts all the AtomDB answers by importance - * (by querying the AttentionBroker) before following up the links (most important ones first). + * LinkTemplate query the AtomDB for the links that match the pattern. In + * addition to this, it attaches values for any variables in the pattern and + * sorts all the AtomDB answers by importance (by querying the AttentionBroker) + * before following up the links (most important ones first). * * An arbitrary number of nested levels are allowed. For instance: * @@ -70,12 +72,15 @@ class LinkTemplate : public Source { // Constructors and destructors /** - * Constructor expects an array of QueryElements which can be Terminals or nested LinkTemplate. + * Constructor expects an array of QueryElements which can be Terminals or + * nested LinkTemplate. * - * @param type Link type or WILDCARD to indicate that the link type doesn't matter. - * @param targets An array with targets which can each be a Terminal or a nested LinkTemplate. - * @param context An optional string defining the context used by the AttentionBroker to - * consider STI (short term importance). + * @param type Link type or WILDCARD to indicate that the link type doesn't + * matter. + * @param targets An array with targets which can each be a Terminal or a + * nested LinkTemplate. + * @param context An optional string defining the context used by the + * AttentionBroker to consider STI (short term importance). */ LinkTemplate(const string& type, const array& targets, @@ -93,8 +98,9 @@ class LinkTemplate : public Source { this->handle_keys[0] = (wildcard_flag ? (char*) AtomDB::WILDCARD.c_str() : named_type_hash((char*) type.c_str())); for (unsigned int i = 1; i <= ARITY; i++) { - // It's safe to get stored shared_ptr's raw pointer here because handle_keys[] - // is used solely in this scope so it's guaranteed that handle will not be freed. + // It's safe to get stored shared_ptr's raw pointer here because + // handle_keys[] is used solely in this scope so it's guaranteed that + // handle will not be freed. if (targets[i - 1]->is_terminal) { this->handle_keys[i] = ((Terminal*) targets[i - 1])->handle.get(); } else { @@ -106,9 +112,9 @@ class LinkTemplate : public Source { if (!wildcard_flag) { free(this->handle_keys[0]); } - // This is correct. id is not necessarily a handle but an identifier. It just happens - // that we want the string for this identifier to be the same as the string representing - // the handle. + // This is correct. id is not necessarily a handle but an identifier. It + // just happens that we want the string for this identifier to be the same + // as the string representing the handle. this->id = this->handle.get() + std::to_string(LinkTemplate::next_instance_count()); } diff --git a/src/query_engine/query_element/Operator.h b/src/query_engine/query_element/Operator.h index 70ba51f..8090c16 100644 --- a/src/query_engine/query_element/Operator.h +++ b/src/query_engine/query_element/Operator.h @@ -12,14 +12,15 @@ using namespace std; namespace query_element { /** - * Superclass for elements which represent logic operators on LinkTemplate results (e.g. AND, - * OR and NOT). + * Superclass for elements which represent logic operators on LinkTemplate + * results (e.g. AND, OR and NOT). * * Operator adds the required QueryNode elements to connect either with: * - * - one or more QueryElement downstream in the query tree (each of them can be either - * Operator or SOurce). - * - one QueryElement upstream in the query tree which can be another Operator or a Sink. + * - one or more QueryElement downstream in the query tree (each of them can + * be either Operator or SOurce). + * - one QueryElement upstream in the query tree which can be another + * Operator or a Sink. */ template class Operator : public QueryElement { @@ -30,14 +31,16 @@ class Operator : public QueryElement { /** * Constructor. * - * @param clauses Array of QueryElement, each of them a clause in the operation. + * @param clauses Array of QueryElement, each of them a clause in the + * operation. */ Operator(const array& clauses) { initialize((QueryElement**) clauses.data()); } /** * Constructor. * - * @param clauses Array of QueryElement, each of them a clause in the operation. + * @param clauses Array of QueryElement, each of them a clause in the + * operation. */ Operator(QueryElement** clauses) { initialize(clauses); } @@ -50,10 +53,10 @@ class Operator : public QueryElement { // QueryElement API /** - * Sets up buffers for communication between this operator and its upstream and downstream - * QueryElements. Initializes a single QueryNodeClient for the upstream connection and - * N QueryNodeServer elements for the downstream connections, each corresponding to a clause - * in the operation. + * Sets up buffers for communication between this operator and its upstream + * and downstream QueryElements. Initializes a single QueryNodeClient for the + * upstream connection and N QueryNodeServer elements for the downstream + * connections, each corresponding to a clause in the operation. */ virtual void setup_buffers() { if (this->subsequent_id == "") { @@ -74,8 +77,8 @@ class Operator : public QueryElement { } /** - * Gracefully shuts down the QueryNodes attached to the upstream and downstream communication - * in the query tree. + * Gracefully shuts down the QueryNodes attached to the upstream and + * downstream communication in the query tree. */ virtual void graceful_shutdown() { if (is_flow_finished()) { diff --git a/src/query_engine/query_element/Or.h b/src/query_engine/query_element/Or.h index fe78900..ea1a009 100644 --- a/src/query_engine/query_element/Or.h +++ b/src/query_engine/query_element/Or.h @@ -1,53 +1,50 @@ #ifndef _QUERY_ELEMENT_OR_H #define _QUERY_ELEMENT_OR_H -#include #include -#include "Operator.h" +#include + #include "HandlesAnswer.h" +#include "Operator.h" using namespace std; namespace query_element { - /** * QueryElement representing an OR logic operator. * - * Or operates on N clauses. Each clause can be either a Source or another Operator. + * Or operates on N clauses. Each clause can be either a Source or another + * Operator. */ template class Or : public Operator { - -public: - + public: // -------------------------------------------------------------------------------------------- // Constructors and destructors /** * Constructor. * - * @param clauses Array with N clauses (each clause is supposed to be a Source or an Operator). + * @param clauses Array with N clauses (each clause is supposed to be a Source + * or an Operator). */ - Or(QueryElement **clauses) : Operator(clauses) { - initialize(clauses); - } + Or(QueryElement** clauses) : Operator(clauses) { initialize(clauses); } /** * Constructor. * - * @param clauses Array with N clauses (each clause is supposed to be a Source or an Operator). + * @param clauses Array with N clauses (each clause is supposed to be a Source + * or an Operator). */ - Or(const array &clauses) : Operator(clauses) { - initialize((QueryElement **) clauses.data()); + Or(const array& clauses) : Operator(clauses) { + initialize((QueryElement**) clauses.data()); } /** * Destructor. */ - ~Or() { - graceful_shutdown(); - } + ~Or() { graceful_shutdown(); } // -------------------------------------------------------------------------------------------- // QueryElement API @@ -64,19 +61,18 @@ class Or : public Operator { this->operator_thread = NULL; } } - + // -------------------------------------------------------------------------------------------- // Private stuff -private: - - vector query_answer[N]; + private: + vector query_answer[N]; unsigned int next_input_to_process[N]; bool all_answers_arrived[N]; bool no_more_answers_to_arrive; - thread *operator_thread; + thread* operator_thread; - void initialize(QueryElement **clauses) { + void initialize(QueryElement** clauses) { this->operator_thread = NULL; for (unsigned int i = 0; i < N; i++) { this->next_input_to_process[i] = 0; @@ -95,7 +91,7 @@ class Or : public Operator { bool ready_to_process_candidate() { for (unsigned int i = 0; i < N; i++) { - if ((! this->all_answers_arrived[i]) && + if ((!this->all_answers_arrived[i]) && (this->query_answer[i].size() <= (this->next_input_to_process[i] + 1))) { return false; } @@ -107,17 +103,17 @@ class Or : public Operator { if (this->no_more_answers_to_arrive) { return; } - HandlesAnswer *answer; + HandlesAnswer* answer; unsigned int all_arrived_count = 0; bool no_new_answer = true; for (unsigned int i = 0; i < N; i++) { - while ((answer = dynamic_cast(this->input_buffer[i]->pop_query_answer())) != NULL) { + while ((answer = dynamic_cast(this->input_buffer[i]->pop_query_answer())) != + NULL) { no_new_answer = false; this->query_answer[i].push_back(answer); } if (this->input_buffer[i]->is_query_answers_empty() && this->input_buffer[i]->is_query_answers_finished()) { - this->all_answers_arrived[i] = true; all_arrived_count++; } @@ -145,24 +141,22 @@ class Or : public Operator { double best_importance = -1; for (unsigned int i = 0; i < N; i++) { if (this->next_input_to_process[i] < this->query_answer[i].size()) { - if (this->query_answer[i][this->next_input_to_process[i]]->importance > best_importance) { + if (this->query_answer[i][this->next_input_to_process[i]]->importance > + best_importance) { best_importance = this->query_answer[i][this->next_input_to_process[i]]->importance; best_index = i; } } } if (best_importance < 0) { - Utils::error ("Invalid state in OR operation"); + Utils::error("Invalid state in OR operation"); } return best_index; } void or_operator_method() { - do { - if (QueryElement::is_flow_finished() || - this->output_buffer->is_query_answers_finished()) { - + if (QueryElement::is_flow_finished() || this->output_buffer->is_query_answers_finished()) { return; } @@ -171,41 +165,43 @@ class Or : public Operator { return; } ingest_newly_arrived_answers(); - } while (! ready_to_process_candidate()); + } while (!ready_to_process_candidate()); cout << "XXXXXXX 1" << endl; if (processed_all_input()) { - cout << "XXXXXXX 2" << endl; + cout << "XXXXXXX 2" << endl; bool all_finished_flag = true; for (unsigned int i = 0; i < N; i++) { - if (! this->input_buffer[i]->is_query_answers_finished()) { + if (!this->input_buffer[i]->is_query_answers_finished()) { all_finished_flag = false; break; } } - cout << "XXXXXXX 3" << endl; - if (all_finished_flag && - ! this->output_buffer->is_query_answers_finished() && - // processed_all_input() is double-checked on purpose to avoid race condition + cout << "XXXXXXX 3" << endl; + if (all_finished_flag && !this->output_buffer->is_query_answers_finished() && + // processed_all_input() is double-checked on purpose to avoid race + // condition processed_all_input()) { this->output_buffer->query_answers_finished(); } - cout << "XXXXXXX 4" << endl; + cout << "XXXXXXX 4" << endl; Utils::sleep(); continue; } cout << "XXXXXXX 5" << endl; - + unsigned int selected_clause = select_answer(); cout << "XXXXXXX 6" << endl; - HandlesAnswer *selected_query_answer = this->query_answer[selected_clause][this->next_input_to_process[selected_clause]++]; - cout << std::to_string(selected_clause) << ": " << selected_query_answer->to_string() << endl; + HandlesAnswer* selected_query_answer = + this->query_answer[selected_clause][this->next_input_to_process[selected_clause]++]; + cout << std::to_string(selected_clause) << ": " << selected_query_answer->to_string() + << endl; this->output_buffer->add_query_answer(selected_query_answer); cout << "XXXXXXX 7" << endl; } while (true); } }; -} // namespace query_element +} // namespace query_element -#endif // _QUERY_ELEMENT_OR_H +#endif // _QUERY_ELEMENT_OR_H diff --git a/src/query_engine/query_element/QueryElement.cc b/src/query_engine/query_element/QueryElement.cc index af326ac..49d456b 100644 --- a/src/query_engine/query_element/QueryElement.cc +++ b/src/query_engine/query_element/QueryElement.cc @@ -10,8 +10,7 @@ QueryElement::QueryElement() { this->is_terminal = false; } -QueryElement::~QueryElement() { -} +QueryElement::~QueryElement() {} // ------------------------------------------------------------------------------------------------ // Protected methods diff --git a/src/query_engine/query_element/QueryElement.h b/src/query_engine/query_element/QueryElement.h index fc702b3..a9b2325 100644 --- a/src/query_engine/query_element/QueryElement.h +++ b/src/query_engine/query_element/QueryElement.h @@ -1,10 +1,11 @@ #ifndef _QUERY_ELEMENT_QUERYELEMENT_H #define _QUERY_ELEMENT_QUERYELEMENT_H -#include #include -#include "Utils.h" +#include + #include "QueryNode.h" +#include "Utils.h" #define DEBUG @@ -15,43 +16,48 @@ using namespace commons; namespace query_element { /** - * Basic element in the class hierarchy which represents boolean logical expression involving - * nodes, links and patterns. + * Basic element in the class hierarchy which represents boolean logical + * expression involving nodes, links and patterns. * - * Boolean logical expressions are formed by logical operators (AND, OR, NOT) and - * operands (Node, Link and LinkTemplate). Nested expression are allowed. AND and OR may operate - * on any number (> 1) of arguments while NOT takes a single argument. + * Boolean logical expressions are formed by logical operators (AND, OR, NOT) + * and operands (Node, Link and LinkTemplate). Nested expression are allowed. + * AND and OR may operate on any number (> 1) of arguments while NOT takes a + * single argument. * - * Nodes are defined by type+name. Links are defined by type+targets. LinkTemplates are defined - * like Links, where the Link type and any number of targets may be wildcards (actually, wildcards - * are named variables which are unified as the query is executed). LinkTemplates can also be - * nested, i.e., one of the targets of a LinkTemplate can be another LinkTemplate. + * Nodes are defined by type+name. Links are defined by type+targets. + * LinkTemplates are defined like Links, where the Link type and any number of + * targets may be wildcards (actually, wildcards are named variables which are + * unified as the query is executed). LinkTemplates can also be nested, i.e., + * one of the targets of a LinkTemplate can be another LinkTemplate. * - * There's no limit in the number of nesting levels of LinkTemplates or boolean expressions. + * There's no limit in the number of nesting levels of LinkTemplates or boolean + * expressions. * - * A query can be understood as a tree whose nodes are QueryElements. Internal nodes are - * logical operators and leaves are either Links or LinkTemplates (nested or not). + * A query can be understood as a tree whose nodes are QueryElements. Internal + * nodes are logical operators and leaves are either Links or LinkTemplates + * (nested or not). * - * The query engine we implement here uses the Nodes/Links values that satisfy the leaves in this - * tree and flows them up through the internal nodes (logical operators) until they reach the root - * of the tree. In this path, some links are dropped because they don't satisfy the properties - * required by the operators or they don't satisfy a proper unification in the set of variables. + * The query engine we implement here uses the Nodes/Links values that satisfy + * the leaves in this tree and flows them up through the internal nodes (logical + * operators) until they reach the root of the tree. In this path, some links + * are dropped because they don't satisfy the properties required by the + * operators or they don't satisfy a proper unification in the set of variables. * * Links that reach the root of the tree are considered actual query answers. * - * Each QueryElement is an element in a distributed algorithm, with one or more threads processing - * its inputs and generating outputs according to the logic of each element. A communication - * framework is used to flow the links up through the tree using our DistributedAlgorithmNode - * which is essentially a framework to implement the basic functionalities required by a - * distributed algorithm. Since this framework allows communication either intra-process and - * extra-process (in the same machine or in different ones), we can have QueryElements of the - * same tree (i.e. of the same query) being processed in different machines or all of them in the - * same machine (either in the same process or in different processes). + * Each QueryElement is an element in a distributed algorithm, with one or more + * threads processing its inputs and generating outputs according to the logic + * of each element. A communication framework is used to flow the links up + * through the tree using our DistributedAlgorithmNode which is essentially a + * framework to implement the basic functionalities required by a distributed + * algorithm. Since this framework allows communication either intra-process and + * extra-process (in the same machine or in different ones), we can have + * QueryElements of the same tree (i.e. of the same query) being processed in + * different machines or all of them in the same machine (either in the same + * process or in different processes). */ class QueryElement { - -public: - + public: string id; string subsequent_id; @@ -69,50 +75,51 @@ class QueryElement { // API to be extended by concrete subclasses /** - * Setup QueryNodes used by concrete implementations of QueryElements. This method is called - * after all ids and other topological-related setup in the query tree is finished. + * Setup QueryNodes used by concrete implementations of QueryElements. This + * method is called after all ids and other topological-related setup in the + * query tree is finished. */ virtual void setup_buffers() = 0; /** - * Synchronously request this QueryElement to shutdown any threads it may have spawned. + * Synchronously request this QueryElement to shutdown any threads it may have + * spawned. */ virtual void graceful_shutdown() = 0; /** - * Indicates whether this QueryElement is a Terminal (i.e. Node, Link or Variable). + * Indicates whether this QueryElement is a Terminal (i.e. Node, Link or + * Variable). */ bool is_terminal; -protected: - + protected: /** - * Return true iff this QueryElement have finished its work in the flow of links up through - * the query tree. + * Return true iff this QueryElement have finished its work in the flow of + * links up through the query tree. * - * When this method return true, it means that all the QueryElements below than in the chain - * have already provided all the links they are supposed to and this QueryElement have already - * processed all of them and delivered all the links that are supposed to pass through the flow - * to the upper element in the tree. In other words, this QueryElement have no further work - * to do. + * When this method return true, it means that all the QueryElements below + * than in the chain have already provided all the links they are supposed to + * and this QueryElement have already processed all of them and delivered all + * the links that are supposed to pass through the flow to the upper element + * in the tree. In other words, this QueryElement have no further work to do. * - * @return true iff this QueryElement have finished its work in the flow of links up througth - * the query tree. + * @return true iff this QueryElement have finished its work in the flow of + * links up througth the query tree. */ bool is_flow_finished(); /** - * Sets a flag to indicate that this QueryElement have finished its work in the query. See - * comments in method is_flow_finished(). + * Sets a flag to indicate that this QueryElement have finished its work in + * the query. See comments in method is_flow_finished(). */ void set_flow_finished(); -private: - + private: bool flow_finished; mutex flow_finished_mutex; }; -} // namespace query_element +} // namespace query_element -#endif // _QUERY_ELEMENT_QUERYELEMENT_H +#endif // _QUERY_ELEMENT_QUERYELEMENT_H diff --git a/src/query_engine/query_element/RemoteIterator.h b/src/query_engine/query_element/RemoteIterator.h index af9802a..8c52c6a 100644 --- a/src/query_engine/query_element/RemoteIterator.h +++ b/src/query_engine/query_element/RemoteIterator.h @@ -1,38 +1,37 @@ #ifndef _QUERY_ELEMENT_REMOTEITERATOR_H #define _QUERY_ELEMENT_REMOTEITERATOR_H -#include "QueryElement.h" #include "QueryAnswer.h" +#include "QueryElement.h" using namespace std; namespace query_element { /** - * A special case of QueryElement because RemoteIterator is not actually an element of the - * query tree itself but rather a utility class used to remotely connect to the sink of a query - * tree (RemoteSink). + * A special case of QueryElement because RemoteIterator is not actually an + * element of the query tree itself but rather a utility class used to remotely + * connect to the sink of a query tree (RemoteSink). * - * Basically, the goal of this class is to allow a caller to request a query execution remotely - * and iterate through the results using the RemoteIterator. + * Basically, the goal of this class is to allow a caller to request a query + * execution remotely and iterate through the results using the RemoteIterator. * - * NB Like Iterator in this same package, this is not a std::iterator as the behavior we'd expect - * of a std::iterator doesn't fit well with the asynchronous nature of QueryElement processing. - * Instead, this class provides only two methods: one to pop and return the next - * query answers and another to check if more answers can still be expected. + * NB Like Iterator in this same package, this is not a std::iterator as the + * behavior we'd expect of a std::iterator doesn't fit well with the + * asynchronous nature of QueryElement processing. Instead, this class provides + * only two methods: one to pop and return the next query answers and another to + * check if more answers can still be expected. */ template class RemoteIterator : public QueryElement { - -public: - + public: /** * Constructor. * - * @param local_id The id of this element in the network which connects to the RemoteSink. - * Typically is something like "host:port". + * @param local_id The id of this element in the network which connects to the + * RemoteSink. Typically is something like "host:port". */ - RemoteIterator(const string &local_id); + RemoteIterator(const string& local_id); /** * Destructor. @@ -49,33 +48,34 @@ class RemoteIterator : public QueryElement { // Iterator API /** - * Return true when all query answers has been processed AND all the query answers - * that reached this QueryElement has been pop'ed out using the method pop(). + * Return true when all query answers has been processed AND all the query + * answers that reached this QueryElement has been pop'ed out using the method + * pop(). * - * @return true iff all query answers has been processed AND all the query answers - * that reached this QueryElement has been pop'ed out using the method pop(). + * @return true iff all query answers has been processed AND all the query + * answers that reached this QueryElement has been pop'ed out using the method + * pop(). */ bool finished(); /** * Return the next query answer or NULL if none are currently available. * - * NB a NULL return DOESN'T mean that the query answers are over. It means that there - * are no query answers available now. Because of the asynchronous nature of QueryElement - * processing, more query answers can arrive later. + * NB a NULL return DOESN'T mean that the query answers are over. It means + * that there are no query answers available now. Because of the asynchronous + * nature of QueryElement processing, more query answers can arrive later. * * @return the next query answer or NULL if none are currently available. */ - QueryAnswer *pop(); - -private: + QueryAnswer* pop(); + private: shared_ptr> remote_input_buffer; string local_id; }; -} // namespace query_element +} // namespace query_element #include "RemoteIterator.cc" -#endif // _QUERY_ELEMENT_REMOTEITERATOR_H +#endif // _QUERY_ELEMENT_REMOTEITERATOR_H diff --git a/src/query_engine/query_element/RemoteSink.h b/src/query_engine/query_element/RemoteSink.h index 04f74c9..04d0063 100644 --- a/src/query_engine/query_element/RemoteSink.h +++ b/src/query_engine/query_element/RemoteSink.h @@ -12,7 +12,8 @@ using namespace std; namespace query_element { /** - * A special sink which forwards the query results to a remote QueryElement (e.g. a RemoteIterator). + * A special sink which forwards the query results to a remote QueryElement + * (e.g. a RemoteIterator). */ template class RemoteSink : public Sink { @@ -21,9 +22,11 @@ class RemoteSink : public Sink { * Constructor. * * @param precedent QueryElement just below in the query tree. - * @param query_answer_processors List of processors to be applied to the query answers. - * @param delete_precedent_on_destructor If true, the destructor of this QueryElement will - * also destruct the passed precedent QueryElement (defaulted to false). + * @param query_answer_processors List of processors to be applied to the + * query answers. + * @param delete_precedent_on_destructor If true, the destructor of this + * QueryElement will also destruct the passed precedent QueryElement + * (defaulted to false). */ RemoteSink(QueryElement* precedent, vector>&& query_answer_processors, @@ -38,8 +41,8 @@ class RemoteSink : public Sink { // QueryElement API /** - * Gracefully shuts down the queue processor thread and the remote communication QueryNodes - * present in this QueryElement. + * Gracefully shuts down the queue processor thread and the remote + * communication QueryNodes present in this QueryElement. */ virtual void graceful_shutdown(); diff --git a/src/query_engine/query_element/Sink.cc b/src/query_engine/query_element/Sink.cc index 3735d3a..8246c82 100644 --- a/src/query_engine/query_element/Sink.cc +++ b/src/query_engine/query_element/Sink.cc @@ -8,12 +8,10 @@ using namespace query_element; // Constructors and destructors template -Sink::Sink( - QueryElement *precedent, - const string &id, - bool delete_precedent_on_destructor, - bool setup_buffers_flag) { - +Sink::Sink(QueryElement* precedent, + const string& id, + bool delete_precedent_on_destructor, + bool setup_buffers_flag) { this->precedent = precedent; this->id = id; this->delete_precedent_on_destructor = delete_precedent_on_destructor; diff --git a/src/query_engine/query_element/Sink.h b/src/query_engine/query_element/Sink.h index b0b84dd..3054cf0 100644 --- a/src/query_engine/query_element/Sink.h +++ b/src/query_engine/query_element/Sink.h @@ -8,35 +8,37 @@ using namespace std; namespace query_element { /** - * Superclass for elements that represent the root in a query tree of QueryElement. + * Superclass for elements that represent the root in a query tree of + * QueryElement. * - * It's a "sink" in the sense of being an element where the flow of links stops, going - * nowhere further. + * It's a "sink" in the sense of being an element where the flow of links stops, + * going nowhere further. * - * Sink adds the required DistributedAlgorithmNode (actually a specialized version of it - * named QueryNode) and exposes a public API to interact with it transparently. Basically, - * a server version of QueryNode (i.e. a ServerQueryNode) is setup to communicate with - * a remote ClientQueryNode which is located in the QueryElement just below in the query tree. + * Sink adds the required DistributedAlgorithmNode (actually a specialized + * version of it named QueryNode) and exposes a public API to interact with it + * transparently. Basically, a server version of QueryNode (i.e. a + * ServerQueryNode) is setup to communicate with a remote ClientQueryNode which + * is located in the QueryElement just below in the query tree. */ template class Sink : public QueryElement { - -public: - + public: /** - * Constructor expects that the QueryElement below in the tree is already constructed. + * Constructor expects that the QueryElement below in the tree is already + * constructed. * * @param precedent QueryElement just below in the query tree. * @param id Unique id for this QueryElement. - * @param delete_precedent_on_destructor If true, the destructor of this QueryElement will - * also destruct the passed precedent QueryElement (defaulted to false). - * @param setup_buffers_flag If true, the setup_buffers() method is called in the constructor. + * @param delete_precedent_on_destructor If true, the destructor of this + * QueryElement will also destruct the passed precedent QueryElement + * (defaulted to false). + * @param setup_buffers_flag If true, the setup_buffers() method is called in + * the constructor. */ - Sink( - QueryElement *precedent, - const string &id, - bool delete_precedent_on_destructor = false, - bool setup_buffers_flag = true); + Sink(QueryElement* precedent, + const string& id, + bool delete_precedent_on_destructor = false, + bool setup_buffers_flag = true); /** * Destructor. @@ -52,23 +54,21 @@ class Sink : public QueryElement { virtual void graceful_shutdown(); /** - * Setup a ServerQueryNode to commnunicate with one or more QueryElement just below in the - * query tree. + * Setup a ServerQueryNode to commnunicate with one or more QueryElement just + * below in the query tree. */ virtual void setup_buffers(); -protected: - + protected: shared_ptr> input_buffer; - QueryElement *precedent; - -private: + QueryElement* precedent; + private: bool delete_precedent_on_destructor; }; -} // namespace query_element +} // namespace query_element #include "Sink.cc" -#endif // _QUERY_ELEMENT_SINK_H +#endif // _QUERY_ELEMENT_SINK_H diff --git a/src/query_engine/query_element/Source.h b/src/query_engine/query_element/Source.h index 48b3821..fa51240 100644 --- a/src/query_engine/query_element/Source.h +++ b/src/query_engine/query_element/Source.h @@ -9,20 +9,22 @@ using namespace std; namespace query_element { /** - * Superclass for elements that represent leaves in the query tree of QueryElement. + * Superclass for elements that represent leaves in the query tree of + * QueryElement. * - * Source adds the required DistributedAlgorithmNode (actually a specialized version of it - * named QueryNode) and exposes a public API to interact with it transparently. Basically, - * a client version of QueryNode (i.e. a ClientQueryNode) is setup to communicate with - * a remote ServerQueryNode which is located in the QueryElement just above in the query tree. + * Source adds the required DistributedAlgorithmNode (actually a specialized + * version of it named QueryNode) and exposes a public API to interact with it + * transparently. Basically, a client version of QueryNode (i.e. a + * ClientQueryNode) is setup to communicate with a remote ServerQueryNode which + * is located in the QueryElement just above in the query tree. */ class Source : public QueryElement { public: /** - * Sources tipically need to communicate with the AttentionBroker in order to sort links - * by importance. AttentionBroker is supposed to be running in the same machine as all - * Source elements so only a port number is required. Here we provide a default value - * in the case none is passed in constructor. + * Sources tipically need to communicate with the AttentionBroker in order to + * sort links by importance. AttentionBroker is supposed to be running in the + * same machine as all Source elements so only a port number is required. Here + * we provide a default value in the case none is passed in constructor. */ static string DEFAULT_ATTENTION_BROKER_PORT; diff --git a/src/query_engine/query_element/Terminal.h b/src/query_engine/query_element/Terminal.h index 555ea22..f86e326 100644 --- a/src/query_engine/query_element/Terminal.h +++ b/src/query_engine/query_element/Terminal.h @@ -1,10 +1,11 @@ #ifndef _QUERY_ELEMENT_TERMINAL_H #define _QUERY_ELEMENT_TERMINAL_H -#include #include -#include "QueryElement.h" +#include + #include "AtomDB.h" +#include "QueryElement.h" #include "expression_hasher.h" using namespace std; @@ -16,27 +17,25 @@ namespace query_element { // Abstract Terminal superclass /** - * A QueryElement which represents terminals (i.e. Nodes, Links and Variables) in the query tree. + * A QueryElement which represents terminals (i.e. Nodes, Links and Variables) + * in the query tree. */ class Terminal : public QueryElement { - -protected: - + protected: /** * Protected constructor. */ Terminal() : QueryElement() { this->handle = shared_ptr{}; this->is_variable = false; - this->is_terminal = true; // overrrides QueryElement default + this->is_terminal = true; // overrrides QueryElement default } -public: - + public: /** * Destructor. */ - ~Terminal() {}; + ~Terminal(){}; /** * Empty implementation. There are no QueryNode element to setup. @@ -44,13 +43,14 @@ class Terminal : public QueryElement { void virtual setup_buffers() {} /** - * Empty implementation. There are no QueryNode element or local thread to shut down. + * Empty implementation. There are no QueryNode element or local thread to + * shut down. */ void virtual graceful_shutdown() {} - + /** - * Returns a string representation of this Terminal (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Terminal (mainly for debugging; not + * optimized to production environment). */ virtual string to_string() = 0; @@ -67,7 +67,8 @@ class Terminal : public QueryElement { /** * Name of the terminal. * - * Actually, only Nodes and Variables have names; Links' name is an empty string. + * Actually, only Nodes and Variables have names; Links' name is an empty + * string. */ string name; }; @@ -79,24 +80,22 @@ class Terminal : public QueryElement { * QueryElement which represents a node. */ class Node : public Terminal { - -public: - + public: /** * Constructor. * * @param type Type of the node. * @param name Name of the node. */ - Node(const string &type, const string &name) : Terminal() { + Node(const string& type, const string& name) : Terminal() { this->type = type; this->name = name; - this->handle = shared_ptr(terminal_hash((char *) type.c_str(), (char *) name.c_str())); + this->handle = shared_ptr(terminal_hash((char*) type.c_str(), (char*) name.c_str())); } /** - * Returns a string representation of this Node (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Node (mainly for debugging; not + * optimized to production environment). */ string to_string() { return "<" + this->type + ", " + this->name + ", " + string(this->handle.get()) + ">"; @@ -116,26 +115,25 @@ class Node : public Terminal { */ template class Link : public Terminal { - -public: - + public: /** * Constructor. * * @param type Type of the Link. * @params targets Array with targets of the Link. Targets are supposed to be - * handles (i.e. strings). No nesting of Nodes or other Links are allowed. + * handles (i.e. strings). No nesting of Nodes or other Links are + * allowed. */ - Link(const string &type, const array &targets) : Terminal() { + Link(const string& type, const array& targets) : Terminal() { this->name = ""; this->type = type; this->targets = targets; this->arity = ARITY; - char *handle_keys[ARITY + 1]; - handle_keys[0] = (char *) named_type_hash((char *) type.c_str()); + char* handle_keys[ARITY + 1]; + handle_keys[0] = (char*) named_type_hash((char*) type.c_str()); for (unsigned int i = 1; i < (ARITY + 1); i++) { - if (targets[i - 1]->is_terminal && ! ((Terminal *) targets[i - 1])->is_variable) { - handle_keys[i] = ((Terminal *) targets[i - 1])->handle.get(); + if (targets[i - 1]->is_terminal && !((Terminal*) targets[i - 1])->is_variable) { + handle_keys[i] = ((Terminal*) targets[i - 1])->handle.get(); } else { Utils::error("Invalid Link definition"); } @@ -145,13 +143,13 @@ class Link : public Terminal { } /** - * Returns a string representation of this Node (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Node (mainly for debugging; not + * optimized to production environment). */ string to_string() { string answer = "(" + this->type + ", ["; for (unsigned int i = 0; i < this->arity; i++) { - answer += ((Terminal *) this->targets[i])->to_string(); + answer += ((Terminal*) this->targets[i])->to_string(); if (i != (this->arity - 1)) { answer += ", "; } @@ -173,7 +171,7 @@ class Link : public Terminal { /** * Targets of the Link. */ - array targets; + array targets; }; // ------------------------------------------------------------------------------------------------- @@ -183,29 +181,25 @@ class Link : public Terminal { * QueryElement which represents a variable. */ class Variable : public Terminal { - -public: - + public: /** * Constructor. * * @param name Name of the Variable. */ - Variable(const string &name) : Terminal() { + Variable(const string& name) : Terminal() { this->name = name; - this->handle = shared_ptr(strdup((char *) AtomDB::WILDCARD.c_str())); + this->handle = shared_ptr(strdup((char*) AtomDB::WILDCARD.c_str())); this->is_variable = true; } /** - * Returns a string representation of this Variable (mainly for debugging; not optimized to - * production environment). + * Returns a string representation of this Variable (mainly for debugging; not + * optimized to production environment). */ - string to_string() { - return "$(" + this->name + ")"; - } + string to_string() { return "$(" + this->name + ")"; } }; -} // namespace query_element +} // namespace query_element -#endif // _QUERY_ELEMENT_TERMINAL_H +#endif // _QUERY_ELEMENT_TERMINAL_H diff --git a/src/scripts/bazel.sh b/src/scripts/bazel.sh index 03e306a..ea6470a 100755 --- a/src/scripts/bazel.sh +++ b/src/scripts/bazel.sh @@ -9,29 +9,17 @@ BAZEL_CMD="/opt/bazel/bazelisk" # local paths LOCAL_WORKDIR=$(pwd) LOCAL_BIN_DIR=$LOCAL_WORKDIR/src/bin -LOCAL_ASPECT_CACHE="$HOME/.cache/das/aspect" -LOCAL_BAZEL_CACHE="$HOME/.cache/das/bazel" -LOCAL_BAZELISK_CACHE="$HOME/.cache/das/bazelisk" -LOCAL_PIPTOOLS_CACHE="$HOME/.cache/das/pip-tools" -LOCAL_PIP_CACHE="$HOME/.cache/das/pip" +LOCAL_CACHE="$HOME/.cache/das" mkdir -p \ - "$LOCAL_ASPECT_CACHE" \ "$LOCAL_BIN_DIR" \ - "$LOCAL_BAZEL_CACHE" \ - "$LOCAL_BAZELISK_CACHE" \ - "$LOCAL_PIPTOOLS_CACHE" \ - "$LOCAL_PIP_CACHE" + "$LOCAL_CACHE" # container paths CONTAINER_WORKDIR=/opt/das CONTAINER_WORKSPACE_DIR=/opt/das/src CONTAINER_BIN_DIR=$CONTAINER_WORKSPACE_DIR/bin -CONTAINER_ASPECT_CACHE=/home/"${USER}"/.cache/aspect -CONTAINER_BAZEL_CACHE=/home/"${USER}"/.cache/bazel -CONTAINER_PIP_CACHE=/home/"${USER}"/.cache/pip -CONTAINER_PIPTOOLS_CACHE=/home/"${USER}"/.cache/pip-tools -CONTAINER_BAZELISK_CACHE=/home/"${USER}"/.cache/bazelisk +CONTAINER_CACHE="/home/$USER/.cache" if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then echo "Removing existing container: ${CONTAINER_NAME}" @@ -44,11 +32,7 @@ docker run --rm \ -e BIN_DIR=$CONTAINER_BIN_DIR \ --network=host \ --volume /etc/passwd:/etc/passwd:ro \ - --volume "$LOCAL_PIP_CACHE":"$CONTAINER_PIP_CACHE" \ - --volume "$LOCAL_PIPTOOLS_CACHE":"$CONTAINER_PIPTOOLS_CACHE" \ - --volume "$LOCAL_ASPECT_CACHE":"$CONTAINER_ASPECT_CACHE" \ - --volume "$LOCAL_BAZEL_CACHE":"$CONTAINER_BAZEL_CACHE" \ - --volume "$LOCAL_BAZELISK_CACHE":"$CONTAINER_BAZELISK_CACHE" \ + --volume "$LOCAL_CACHE":"$CONTAINER_CACHE" \ --volume "$LOCAL_WORKDIR":"$CONTAINER_WORKDIR" \ --workdir "$CONTAINER_WORKSPACE_DIR" \ --entrypoint "$BAZEL_CMD" \ diff --git a/src/scripts/build.sh b/src/scripts/build.sh index 86c71e6..fe405b0 100755 --- a/src/scripts/build.sh +++ b/src/scripts/build.sh @@ -8,28 +8,16 @@ CONTAINER_NAME=${IMAGE_NAME}-container # local paths LOCAL_WORKDIR=$(pwd) LOCAL_BIN_DIR=$LOCAL_WORKDIR/src/bin -LOCAL_ASPECT_CACHE="$HOME/.cache/das/aspect" -LOCAL_BAZEL_CACHE="$HOME/.cache/das/bazel" -LOCAL_BAZELISK_CACHE="$HOME/.cache/das/bazelisk" -LOCAL_PIPTOOLS_CACHE="$HOME/.cache/das/pip-tools" -LOCAL_PIP_CACHE="$HOME/.cache/das/pip" +LOCAL_CACHE="${HOME}/.cache/das" mkdir -p \ - $LOCAL_ASPECT_CACHE \ - $LOCAL_BAZEL_CACHE \ - $LOCAL_BAZELISK_CACHE \ $LOCAL_BIN_DIR \ - $LOCAL_PIPTOOLS_CACHE \ - $LOCAL_PIP_CACHE + $LOCAL_CACHE # container paths CONTAINER_WORKDIR=/opt/das CONTAINER_WORKSPACE_DIR=/opt/das/src CONTAINER_BIN_DIR=$CONTAINER_WORKSPACE_DIR/bin -CONTAINER_ASPECT_CACHE=/home/${USER}/.cache/aspect -CONTAINER_BAZEL_CACHE=/home/${USER}/.cache/bazel -CONTAINER_PIP_CACHE=/home/${USER}/.cache/pip -CONTAINER_PIPTOOLS_CACHE=/home/${USER}/.cache/pip-tools -CONTAINER_BAZELISK_CACHE=/home/${USER}/.cache/bazelisk +CONTAINER_CACHE="/home/${USER}/.cache" if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then echo "Removing existing container: ${CONTAINER_NAME}" @@ -41,11 +29,7 @@ docker run --rm \ --name=$CONTAINER_NAME \ -e BIN_DIR=$CONTAINER_BIN_DIR \ --volume /etc/passwd:/etc/passwd:ro \ - --volume $LOCAL_PIP_CACHE:$CONTAINER_PIP_CACHE \ - --volume $LOCAL_PIPTOOLS_CACHE:$CONTAINER_PIPTOOLS_CACHE \ - --volume $LOCAL_ASPECT_CACHE:$CONTAINER_ASPECT_CACHE \ - --volume $LOCAL_BAZEL_CACHE:$CONTAINER_BAZEL_CACHE \ - --volume $LOCAL_BAZELISK_CACHE:$CONTAINER_BAZELISK_CACHE \ + --volume $LOCAL_CACHE:$CONTAINER_CACHE \ --volume $LOCAL_WORKDIR:$CONTAINER_WORKDIR \ --workdir $CONTAINER_WORKSPACE_DIR \ ${IMAGE_NAME} \ diff --git a/src/tests/cpp/and_operator_test.cc b/src/tests/cpp/and_operator_test.cc index e454485..89fa401 100644 --- a/src/tests/cpp/and_operator_test.cc +++ b/src/tests/cpp/and_operator_test.cc @@ -1,11 +1,11 @@ #include #include -#include "gtest/gtest.h" -#include "Source.h" -#include "Sink.h" -#include "HandlesAnswer.h" #include "And.h" +#include "HandlesAnswer.h" +#include "Sink.h" +#include "Source.h" +#include "gtest/gtest.h" #include "test_utils.h" using namespace query_engine; @@ -14,57 +14,44 @@ using namespace query_element; #define SLEEP_DURATION ((unsigned int) 1000) class TestSource : public Source { - - public: - - TestSource(unsigned int count) { - this->id = "TestSource_" + to_string(count); + public: + TestSource(unsigned int count) { this->id = "TestSource_" + to_string(count); } + + ~TestSource() {} + + void add(const char* handle, + double importance, + const array& labels, + const array& values, + bool sleep_flag = true) { + HandlesAnswer* query_answer = new HandlesAnswer(handle, importance); + for (unsigned int i = 0; i < labels.size(); i++) { + query_answer->assignment.assign(labels[i], values[i]); } - - ~TestSource() { - } - - void add( - const char *handle, - double importance, - const array &labels, - const array &values, - bool sleep_flag = true) { - - HandlesAnswer *query_answer = new HandlesAnswer(handle, importance); - for (unsigned int i = 0; i < labels.size(); i++) { - query_answer->assignment.assign(labels[i], values[i]); - } - this->output_buffer->add_query_answer(query_answer); - if (sleep_flag) { - Utils::sleep(SLEEP_DURATION); - } + this->output_buffer->add_query_answer(query_answer); + if (sleep_flag) { + Utils::sleep(SLEEP_DURATION); } + } - void query_answers_finished() { - return this->output_buffer->query_answers_finished(); - } + void query_answers_finished() { return this->output_buffer->query_answers_finished(); } }; class TestSink : public Sink { - public: - TestSink(QueryElement *precedent) : - Sink(precedent, "TestSink(" + precedent->id + ")") { - } - ~TestSink() { - } - bool empty() { return this->input_buffer->is_query_answers_empty(); } - bool finished() { return this->input_buffer->is_query_answers_finished(); } - QueryAnswer *pop() { return this->input_buffer->pop_query_answer(); } + public: + TestSink(QueryElement* precedent) + : Sink(precedent, "TestSink(" + precedent->id + ")") {} + ~TestSink() {} + bool empty() { return this->input_buffer->is_query_answers_empty(); } + bool finished() { return this->input_buffer->is_query_answers_finished(); } + QueryAnswer* pop() { return this->input_buffer->pop_query_answer(); } }; -void check_query_answer( - string tag, - HandlesAnswer *query_answer, - double importance, - unsigned int handles_size, - const array &handles) { - +void check_query_answer(string tag, + HandlesAnswer* query_answer, + double importance, + unsigned int handles_size, + const array& handles) { cout << "check_query_answer(" + tag + ")" << endl; EXPECT_TRUE(double_equals(query_answer->importance, importance)); EXPECT_EQ(query_answer->handles_size, 2); @@ -74,14 +61,14 @@ void check_query_answer( } TEST(AndOperator, basics) { - TestSource source1(1); TestSource source2(2); And<2> and_operator({&source1, &source2}); TestSink sink(&and_operator); - HandlesAnswer *query_answer; + HandlesAnswer* query_answer; - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); // -------------------------------------------------- // Expected processing order: @@ -101,23 +88,30 @@ TEST(AndOperator, basics) { source1.add("h1_0", 0.5, {"v1_0"}, {"1"}); source2.add("h2_0", 0.3, {"v1_1"}, {"2"}); source2.add("h2_1", 0.2, {"v2_1"}, {"1"}); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); source1.add("h1_1", 0.4, {"v1_1"}, {"1"}); - EXPECT_FALSE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_FALSE(sink.empty()); + EXPECT_FALSE(sink.finished()); EXPECT_FALSE((query_answer = dynamic_cast(sink.pop())) == NULL); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); check_query_answer("1", query_answer, 0.5, 2, {"h1_0", "h2_0"}); EXPECT_TRUE(strcmp(query_answer->assignment.get("v1_0"), "1") == 0); EXPECT_TRUE(strcmp(query_answer->assignment.get("v1_1"), "2") == 0); source1.add("h1_2", 0.3, {"v1_2"}, {"1"}); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); source2.add("h2_2", 0.1, {"v2_2"}, {"1"}); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); source1.query_answers_finished(); - EXPECT_TRUE(sink.empty()); EXPECT_FALSE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_FALSE(sink.finished()); source2.query_answers_finished(); Utils::sleep(SLEEP_DURATION); - EXPECT_FALSE(sink.empty()); EXPECT_TRUE(sink.finished()); + EXPECT_FALSE(sink.empty()); + EXPECT_TRUE(sink.finished()); // {"h1_1", "h2_0"} is not popped because it's invalid @@ -144,29 +138,29 @@ TEST(AndOperator, basics) { check_query_answer("9", query_answer, 0.3, 2, {"h1_2", "h2_2"}); Utils::sleep(SLEEP_DURATION); - EXPECT_TRUE(sink.empty()); EXPECT_TRUE(sink.finished()); + EXPECT_TRUE(sink.empty()); + EXPECT_TRUE(sink.finished()); } TEST(AndOperator, operation_logic) { - class ImportanceFitnessPair { - public: + public: double importance; double fitness; ImportanceFitnessPair() {} - ImportanceFitnessPair(const ImportanceFitnessPair &other) { + ImportanceFitnessPair(const ImportanceFitnessPair& other) { this->importance = other.importance; this->fitness = other.fitness; } - ImportanceFitnessPair& operator=(const ImportanceFitnessPair &other) { + ImportanceFitnessPair& operator=(const ImportanceFitnessPair& other) { this->importance = other.importance; this->fitness = other.fitness; return *this; } - bool operator<(const ImportanceFitnessPair &other) const { + bool operator<(const ImportanceFitnessPair& other) const { return this->fitness < other.fitness; } - bool operator>(const ImportanceFitnessPair &other) const { + bool operator>(const ImportanceFitnessPair& other) const { return this->fitness > other.fitness; } }; @@ -178,34 +172,26 @@ TEST(AndOperator, operation_logic) { array, 3> importance; priority_queue fitness_heap; ImportanceFitnessPair pair; - HandlesAnswer *query_answer; - TestSource *source[3]; + HandlesAnswer* query_answer; + TestSource* source[3]; for (unsigned int clause = 0; clause < clause_count; clause++) { source[clause] = new TestSource(clause); } - And<3> *and_operator = new And<3>((QueryElement **) source); - TestSink *sink = new TestSink(and_operator); + And<3>* and_operator = new And<3>((QueryElement**) source); + TestSink* sink = new TestSink(and_operator); for (unsigned int clause = 0; clause < clause_count; clause++) { for (unsigned int link = 0; link < link_count; link++) { importance[clause][link] = random_importance(); } - std::sort( - std::begin(importance[clause]), - std::end(importance[clause]), - std::greater{}); + std::sort(std::begin(importance[clause]), std::end(importance[clause]), std::greater{}); } cout << "QUEUES POPULATION" << endl; for (unsigned int clause = 0; clause < clause_count; clause++) { for (unsigned int link = 0; link < link_count; link++) { - source[clause]->add( - random_handle().c_str(), - importance[clause][link], - {"v"}, - {"1"}, - false); + source[clause]->add(random_handle().c_str(), importance[clause][link], {"v"}, {"1"}, false); } source[clause]->query_answers_finished(); } @@ -215,8 +201,10 @@ TEST(AndOperator, operation_logic) { for (unsigned int i = 0; i < link_count; i++) { for (unsigned int j = 0; j < link_count; j++) { for (unsigned int k = 0; k < link_count; k++) { - pair.importance = importance[0][i] > importance[1][j] ? importance[0][i] : importance[1][j]; - pair.importance = importance[2][k] > pair.importance ? importance[2][k] : pair.importance; + pair.importance = + importance[0][i] > importance[1][j] ? importance[0][i] : importance[1][j]; + pair.importance = + importance[2][k] > pair.importance ? importance[2][k] : pair.importance; pair.fitness = importance[0][i] * importance[1][j] * importance[2][k]; fitness_heap.push(pair); } @@ -227,14 +215,15 @@ TEST(AndOperator, operation_logic) { cout << "TEST CHECKS" << endl; unsigned int count = 0; - while (! (sink->empty() && sink->finished())) { + while (!(sink->empty() && sink->finished())) { if (sink->empty()) { Utils::sleep(); continue; } EXPECT_FALSE((query_answer = dynamic_cast(sink->pop())) == NULL); pair = fitness_heap.top(); - cout << count << " CHECK: " << query_answer->importance << " " << pair.importance << " (" << pair.fitness << ")" << endl; + cout << count << " CHECK: " << query_answer->importance << " " << pair.importance << " (" + << pair.fitness << ")" << endl; EXPECT_TRUE(double_equals(query_answer->importance, pair.importance)); fitness_heap.pop(); count++; diff --git a/src/tests/cpp/attention_broker_server_test.cc b/src/tests/cpp/attention_broker_server_test.cc index 42856a7..57656ad 100644 --- a/src/tests/cpp/attention_broker_server_test.cc +++ b/src/tests/cpp/attention_broker_server_test.cc @@ -1,18 +1,16 @@ -#include -#include - #include #include #include -#include "gtest/gtest.h" - -#include "common.pb.h" -#include "attention_broker.grpc.pb.h" -#include "attention_broker.pb.h" +#include +#include #include "AttentionBrokerServer.h" #include "Utils.h" +#include "attention_broker.grpc.pb.h" +#include "attention_broker.pb.h" +#include "common.pb.h" +#include "gtest/gtest.h" #include "test_utils.h" using namespace attention_broker_server; @@ -24,14 +22,13 @@ bool importance_equals(ImportanceType importance, double v2) { } TEST(AttentionBrokerTest, basics) { - AttentionBrokerServer service; dasproto::Empty empty; dasproto::HandleCount handle_count; dasproto::HandleList handle_list; dasproto::Ack ack; dasproto::ImportanceList importance_list; - ServerContext *context = NULL; + ServerContext* context = NULL; service.ping(context, &empty, &ack); EXPECT_EQ(ack.msg(), "PING"); @@ -44,8 +41,7 @@ TEST(AttentionBrokerTest, basics) { } TEST(AttentionBrokerTest, get_importance) { - - string *handles = build_handle_space(4); + string* handles = build_handle_space(4); AttentionBrokerServer service; dasproto::HandleList handle_list0; @@ -55,7 +51,7 @@ TEST(AttentionBrokerTest, get_importance) { dasproto::Ack ack; dasproto::ImportanceList importance_list1; dasproto::ImportanceList importance_list2; - ServerContext *context = NULL; + ServerContext* context = NULL; (*handle_count.mutable_map())[handles[0]] = 1; (*handle_count.mutable_map())[handles[1]] = 1; diff --git a/src/tests/cpp/das_node_test.cc b/src/tests/cpp/das_node_test.cc index 4cf19a5..feaef6e 100644 --- a/src/tests/cpp/das_node_test.cc +++ b/src/tests/cpp/das_node_test.cc @@ -1,21 +1,19 @@ #include -#include "gtest/gtest.h" -#include "DASNode.h" -#include "AtomDBSingleton.h" #include "AtomDB.h" -#include "Utils.h" +#include "AtomDBSingleton.h" +#include "DASNode.h" #include "HandlesAnswer.h" - +#include "Utils.h" +#include "gtest/gtest.h" #include "test_utils.h" using namespace query_engine; -string handle_to_atom(const char *handle) { - +string handle_to_atom(const char* handle) { shared_ptr db = AtomDBSingleton::get_instance(); shared_ptr document = db->get_atom_document(handle); - shared_ptr targets = db->query_for_targets((char *) handle); + shared_ptr targets = db->query_for_targets((char*) handle); string answer; if (targets != NULL) { @@ -42,18 +40,16 @@ string handle_to_atom(const char *handle) { return answer; } -void check_query( - vector &query, - unsigned int expected_count, - DASNode *das, - DASNode *requestor, - const string &context) { - +void check_query(vector& query, + unsigned int expected_count, + DASNode* das, + DASNode* requestor, + const string& context) { cout << "XXXXXXXXXXXXXXXX DASNode.queries CHECK BEGIN" << endl; - QueryAnswer *query_answer; - RemoteIterator *response = requestor->pattern_matcher_query(query, context); + QueryAnswer* query_answer; + RemoteIterator* response = requestor->pattern_matcher_query(query, context); unsigned int count = 0; - while (! response->finished()) { + while (!response->finished()) { while ((query_answer = response->pop()) == NULL) { if (response->finished()) { break; @@ -63,7 +59,7 @@ void check_query( } if (query_answer != NULL) { cout << "XXXXX " << query_answer->to_string() << endl; - //cout << "XXXXX " << handle_to_atom(query_answer->handles[0]) << endl; + // cout << "XXXXX " << handle_to_atom(query_answer->handles[0]) << endl; count++; } } @@ -77,7 +73,6 @@ void check_query( } TEST(DASNode, queries) { - cout << "XXXXXXXXXXXXXXXX DASNode.queries BEGIN" << endl; setenv("DAS_REDIS_HOSTNAME", "localhost", 1); @@ -91,74 +86,65 @@ TEST(DASNode, queries) { string das_id = "localhost:31700"; string requestor_id = "localhost:31701"; - DASNode *das = new DASNode(das_id); + DASNode* das = new DASNode(das_id); Utils::sleep(1000); - DASNode *requestor = new DASNode(requestor_id, das_id); + DASNode* requestor = new DASNode(requestor_id, das_id); Utils::sleep(1000); - vector q1 = { - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "VARIABLE", "v2" - }; + vector q1 = {"LINK_TEMPLATE", + "Expression", + "3", + "NODE", + "Symbol", + "Similarity", + "VARIABLE", + "v1", + "VARIABLE", + "v2"}; int q1_expected_count = 14; - vector q2 = { - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "NODE", "Symbol", "\"human\"", - "VARIABLE", "v1" - }; + vector q2 = {"LINK_TEMPLATE", + "Expression", + "3", + "NODE", + "Symbol", + "Similarity", + "NODE", + "Symbol", + "\"human\"", + "VARIABLE", + "v1"}; int q2_expected_count = 3; - vector q3 = { - "AND", "2", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "NODE", "Symbol", "\"human\"", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Inheritance", - "VARIABLE", "v1", - "NODE", "Symbol", "\"plant\"" - }; + vector q3 = {"AND", "2", "LINK_TEMPLATE", "Expression", "3", + "NODE", "Symbol", "Similarity", "VARIABLE", "v1", + "NODE", "Symbol", "\"human\"", "LINK_TEMPLATE", "Expression", + "3", "NODE", "Symbol", "Inheritance", "VARIABLE", + "v1", "NODE", "Symbol", "\"plant\""}; int q3_expected_count = 1; - vector q4 = { - "AND", "2", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "VARIABLE", "v2", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v2", - "VARIABLE", "v3" - }; + vector q4 = {"AND", "2", "LINK_TEMPLATE", "Expression", "3", + "NODE", "Symbol", "Similarity", "VARIABLE", "v1", + "VARIABLE", "v2", "LINK_TEMPLATE", "Expression", "3", + "NODE", "Symbol", "Similarity", "VARIABLE", "v2", + "VARIABLE", "v3"}; int q4_expected_count = 26; // TODO: FIX THIS count should be == 1 - vector q5 = { - "OR", "2", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "NODE", "Symbol", "\"human\"", - "LINK_TEMPLATE", "Expression", "3", - "NODE", "Symbol", "Similarity", - "VARIABLE", "v1", - "NODE", "Symbol", "\"snake\"" - }; + vector q5 = {"OR", "2", "LINK_TEMPLATE", "Expression", "3", + "NODE", "Symbol", "Similarity", "VARIABLE", "v1", + "NODE", "Symbol", "\"human\"", "LINK_TEMPLATE", "Expression", + "3", "NODE", "Symbol", "Similarity", "VARIABLE", + "v1", "NODE", "Symbol", "\"snake\""}; int q5_expected_count = 5; check_query(q1, q1_expected_count, das, requestor, "DASNode.queries"); check_query(q2, q2_expected_count, das, requestor, "DASNode.queries"); check_query(q3, q3_expected_count, das, requestor, "DASNode.queries"); - check_query(q4, q4_expected_count, das, requestor, "DASNode.queries"); + check_query(q4, q4_expected_count, das, requestor, "DASNode.queries"); check_query(q5, q5_expected_count, das, requestor, "DASNode.queries"); - //delete(requestor); // TODO: Uncomment this - //delete(das); // TODO: Uncomment this + // delete(requestor); // TODO: Uncomment this + // delete(das); // TODO: Uncomment this cout << "XXXXXXXXXXXXXXXX DASNode.queries END" << endl; } diff --git a/src/tests/cpp/distributed_algorithm_node_test.cc b/src/tests/cpp/distributed_algorithm_node_test.cc index b15f65c..377b5a7 100644 --- a/src/tests/cpp/distributed_algorithm_node_test.cc +++ b/src/tests/cpp/distributed_algorithm_node_test.cc @@ -1,9 +1,9 @@ -#include #include +#include -#include "gtest/gtest.h" -#include "Utils.h" #include "DistributedAlgorithmNode.h" +#include "Utils.h" +#include "gtest/gtest.h" using namespace distributed_algorithm_node; @@ -11,7 +11,7 @@ using namespace distributed_algorithm_node; // Utility classes - concrete subclasses of DistributedAlgorithmNode and Message class TestMessage : public Message { -public: + public: string command; vector args; TestMessage(string command, vector args) { @@ -22,35 +22,28 @@ class TestMessage : public Message { }; class TestNode : public DistributedAlgorithmNode { - -public: - + public: string server_id; bool is_server; string command; vector args; unsigned int node_joined_network_count; - TestNode( - const string &node_id, - const string &server_id, - LeadershipBrokerType leadership_algorithm, - MessageBrokerType messaging_backend, - bool is_server) : DistributedAlgorithmNode( - node_id, - leadership_algorithm, - messaging_backend) { - + TestNode(const string& node_id, + const string& server_id, + LeadershipBrokerType leadership_algorithm, + MessageBrokerType messaging_backend, + bool is_server) + : DistributedAlgorithmNode(node_id, leadership_algorithm, messaging_backend) { this->is_server = is_server; - if (! is_server) { + if (!is_server) { this->server_id = server_id; this->add_peer(server_id); } this->node_joined_network_count = 0; } - virtual ~TestNode() { - } + virtual ~TestNode() {} string cast_leadership_vote() { if (this->is_server) { @@ -60,14 +53,14 @@ class TestNode : public DistributedAlgorithmNode { } } - void node_joined_network(const string &node_id) { + void node_joined_network(const string& node_id) { this->node_joined_network_count += 1; if (is_server) { this->add_peer(node_id); } } - std::shared_ptr message_factory(string &command, vector &args) { + std::shared_ptr message_factory(string& command, vector& args) { std::shared_ptr message = DistributedAlgorithmNode::message_factory(command, args); if (message) { return message; @@ -92,30 +85,17 @@ TEST(DistributedAlgorithmNode, basics) { string server_id = "localhost:30700"; string client1_id = "localhost:30701"; string client2_id = "localhost:30702"; - TestNode *server; - TestNode *client1; - TestNode *client2; - - for (auto messaging_type: {MessageBrokerType::RAM , MessageBrokerType::GRPC}) { + TestNode* server; + TestNode* client1; + TestNode* client2; + for (auto messaging_type : {MessageBrokerType::RAM, MessageBrokerType::GRPC}) { server = new TestNode( - server_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - true); + server_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, true); client1 = new TestNode( - client1_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - false); + client1_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, false); client2 = new TestNode( - client2_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - false); + client2_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, false); EXPECT_FALSE(server->is_leader()); EXPECT_FALSE(client1->is_leader()); @@ -152,40 +132,25 @@ TEST(DistributedAlgorithmNode, basics) { delete client1; delete client2; } - } TEST(DistributedAlgorithmNode, communication) { - string server_id = "localhost:30700"; string client1_id = "localhost:30701"; string client2_id = "localhost:30702"; - TestNode *server; - TestNode *client1; - TestNode *client2; - - for (auto messaging_type: {MessageBrokerType::RAM , MessageBrokerType::GRPC}) { + TestNode* server; + TestNode* client1; + TestNode* client2; + for (auto messaging_type : {MessageBrokerType::RAM, MessageBrokerType::GRPC}) { server = new TestNode( - server_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - true); + server_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, true); server->join_network(); client1 = new TestNode( - client1_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - false); + client1_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, false); client1->join_network(); client2 = new TestNode( - client2_id, - server_id, - LeadershipBrokerType::SINGLE_MASTER_SERVER, - messaging_type, - false); + client2_id, server_id, LeadershipBrokerType::SINGLE_MASTER_SERVER, messaging_type, false); client2->join_network(); Utils::sleep(1000); @@ -198,7 +163,8 @@ TEST(DistributedAlgorithmNode, communication) { EXPECT_EQ(server->node_joined_network_count, 2); EXPECT_EQ(client1->node_joined_network_count, 1); - EXPECT_EQ(client2->node_joined_network_count, 0); // TODO Fix this. This count should be 2 + EXPECT_EQ(client2->node_joined_network_count, + 0); // TODO Fix this. This count should be 2 vector args1 = {"a", "b"}; server->broadcast("c1", args1); diff --git a/src/tests/cpp/handle_trie_test.cc b/src/tests/cpp/handle_trie_test.cc index 10d936f..804f716 100644 --- a/src/tests/cpp/handle_trie_test.cc +++ b/src/tests/cpp/handle_trie_test.cc @@ -2,12 +2,11 @@ #include #include -#include "gtest/gtest.h" - -#include "Utils.h" -#include "expression_hasher.h" #include "HandleTrie.h" #include "RequestSelector.h" +#include "Utils.h" +#include "expression_hasher.h" +#include "gtest/gtest.h" #include "test_utils.h" #define HANDLE_SPACE_SIZE ((unsigned int) 100) @@ -15,26 +14,18 @@ using namespace attention_broker_server; using namespace std; -class TestValue: public HandleTrie::TrieValue { - public: - unsigned int count; - TestValue(int count = 1) { - this->count = count; - } - void merge(TrieValue *other) { - - } +class TestValue : public HandleTrie::TrieValue { + public: + unsigned int count; + TestValue(int count = 1) { this->count = count; } + void merge(TrieValue* other) {} }; -class AccumulatorValue: public HandleTrie::TrieValue { - public: - unsigned int count; - AccumulatorValue() { - this->count = 1; - } - void merge(TrieValue *other) { - count += ((AccumulatorValue *) other)->count; - } +class AccumulatorValue : public HandleTrie::TrieValue { + public: + unsigned int count; + AccumulatorValue() { this->count = 1; } + void merge(TrieValue* other) { count += ((AccumulatorValue*) other)->count; } }; char R_TLB[16] = { @@ -56,196 +47,192 @@ char R_TLB[16] = { 'f', }; -bool visit1(HandleTrie::TrieNode *node, void *data) { - TestValue *value = (TestValue *) node->value; - value->count += *((unsigned int *) data); +bool visit1(HandleTrie::TrieNode* node, void* data) { + TestValue* value = (TestValue*) node->value; + value->count += *((unsigned int*) data); return false; } -bool visit2(HandleTrie::TrieNode *node, void *data) { - TestValue *value = (TestValue *) node->value; +bool visit2(HandleTrie::TrieNode* node, void* data) { + TestValue* value = (TestValue*) node->value; value->count += 1; return false; } -void visitor3(HandleTrie *trie, unsigned int n) { +void visitor3(HandleTrie* trie, unsigned int n) { for (unsigned int i = 0; i < n; i++) { trie->traverse(Utils::flip_coin(), &visit2, NULL); } } - TEST(HandleTrieTest, basics) { - HandleTrie trie(4); - TestValue *value; + TestValue* value; trie.insert("ABCD", new TestValue(3)); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value == NULL); trie.insert("ABCF", new TestValue(4)); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); trie.insert("ABFD", new TestValue(5)); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5); trie.insert("FBCD", new TestValue(6)); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6); trie.insert("AFCD", new TestValue(7)); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7); - value = (TestValue *) trie.lookup("ABFF"); + value = (TestValue*) trie.lookup("ABFF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("AFCF"); + value = (TestValue*) trie.lookup("AFCF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("AFFD"); + value = (TestValue*) trie.lookup("AFFD"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FBCF"); + value = (TestValue*) trie.lookup("FBCF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FBFD"); + value = (TestValue*) trie.lookup("FBFD"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FFCD"); + value = (TestValue*) trie.lookup("FFCD"); EXPECT_TRUE(value == NULL); unsigned int delta = 7; trie.traverse(false, &visit1, &delta); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3 + delta); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4 + delta); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5 + delta); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6 + delta); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7 + delta); } TEST(HandleTrieTest, traverse) { - HandleTrie trie(4); - TestValue *value; + TestValue* value; trie.insert("ABCD", new TestValue(3)); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value == NULL); trie.insert("ABCF", new TestValue(4)); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); trie.insert("ABFD", new TestValue(5)); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5); trie.insert("FBCD", new TestValue(6)); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6); trie.insert("AFCD", new TestValue(7)); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7); - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 3); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 4); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 5); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 6); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value != NULL); EXPECT_TRUE(value->count == 7); - value = (TestValue *) trie.lookup("ABFF"); + value = (TestValue*) trie.lookup("ABFF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("AFCF"); + value = (TestValue*) trie.lookup("AFCF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("AFFD"); + value = (TestValue*) trie.lookup("AFFD"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FBCF"); + value = (TestValue*) trie.lookup("FBCF"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FBFD"); + value = (TestValue*) trie.lookup("FBFD"); EXPECT_TRUE(value == NULL); - value = (TestValue *) trie.lookup("FFCD"); + value = (TestValue*) trie.lookup("FFCD"); EXPECT_TRUE(value == NULL); - vector visitors; + vector visitors; unsigned int n_visits = 100000; unsigned int n_threads = 32; for (unsigned int i = 0; i < n_threads; i++) { visitors.push_back(new thread(&visitor3, &trie, n_visits)); } - for (thread *t: visitors) { + for (thread* t : visitors) { t->join(); } - value = (TestValue *) trie.lookup("ABCD"); + value = (TestValue*) trie.lookup("ABCD"); EXPECT_TRUE(value->count == 3 + n_visits * n_threads); - value = (TestValue *) trie.lookup("ABCF"); + value = (TestValue*) trie.lookup("ABCF"); EXPECT_TRUE(value->count == 4 + n_visits * n_threads); - value = (TestValue *) trie.lookup("ABFD"); + value = (TestValue*) trie.lookup("ABFD"); EXPECT_TRUE(value->count == 5 + n_visits * n_threads); - value = (TestValue *) trie.lookup("FBCD"); + value = (TestValue*) trie.lookup("FBCD"); EXPECT_TRUE(value->count == 6 + n_visits * n_threads); - value = (TestValue *) trie.lookup("AFCD"); + value = (TestValue*) trie.lookup("AFCD"); EXPECT_TRUE(value->count == 7 + n_visits * n_threads); } TEST(HandleTrieTest, merge) { - HandleTrie trie(4); trie.insert("ABCD", new AccumulatorValue()); @@ -265,27 +252,27 @@ TEST(HandleTrieTest, merge) { trie.insert("FFFD", new AccumulatorValue()); trie.insert("FFFF", new AccumulatorValue()); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABCD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABCF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFCD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFCF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFFD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFFF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBCD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBCF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBFD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBFF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCF"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFFD"))->count == 1); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFFF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABCD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABCF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFCD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFCF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFFD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFFF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBCD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBCF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBFD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBFF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCF"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFFD"))->count == 1); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFFF"))->count == 1); trie.insert("ABFF", new AccumulatorValue()); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFF"))->count == 2); trie.insert("FFCD", new AccumulatorValue()); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCD"))->count == 2); trie.insert("ABCD", new AccumulatorValue()); trie.insert("ABCF", new AccumulatorValue()); @@ -304,33 +291,32 @@ TEST(HandleTrieTest, merge) { trie.insert("FFFD", new AccumulatorValue()); trie.insert("FFFF", new AccumulatorValue()); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABCD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABCF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("ABFF"))->count == 3); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFCD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFCF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFFD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("AFFF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBCD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBCF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBFD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FBFF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCD"))->count == 3); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFCF"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFFD"))->count == 2); - EXPECT_TRUE(((AccumulatorValue *) trie.lookup("FFFF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABCD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABCF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("ABFF"))->count == 3); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFCD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFCF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFFD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("AFFF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBCD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBCF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBFD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FBFF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCD"))->count == 3); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFCF"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFFD"))->count == 2); + EXPECT_TRUE(((AccumulatorValue*) trie.lookup("FFFF"))->count == 2); } TEST(HandleTrieTest, random_stress) { - char buffer[1000]; map baseline; - TestValue *value; + TestValue* value; - for (unsigned int key_size: {2, 5, 10, 100}) { + for (unsigned int key_size : {2, 5, 10, 100}) { baseline.clear(); - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); for (unsigned int i = 0; i < 100000; i++) { for (unsigned int j = 0; j < key_size; j++) { buffer[j] = R_TLB[(rand() % 16)]; @@ -341,7 +327,7 @@ TEST(HandleTrieTest, random_stress) { baseline[s] = 0; } baseline[s] = baseline[s] + 1; - value = (TestValue *) trie->lookup(s); + value = (TestValue*) trie->lookup(s); if (value == NULL) { value = new TestValue(); trie->insert(s, value); @@ -350,7 +336,7 @@ TEST(HandleTrieTest, random_stress) { } } for (auto const& pair : baseline) { - value = (TestValue *) trie->lookup(pair.first); + value = (TestValue*) trie->lookup(pair.first); EXPECT_TRUE(value != NULL); EXPECT_EQ(pair.second, value->count); } @@ -361,12 +347,12 @@ TEST(HandleTrieTest, random_stress) { TEST(HandleTrieTest, hasher) { char buffer[1000]; map baseline; - TestValue *value; + TestValue* value; - for (unsigned int key_count: {1, 2, 5}) { + for (unsigned int key_count : {1, 2, 5}) { baseline.clear(); unsigned int key_size = (HANDLE_HASH_SIZE - 1) * key_count; - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); for (unsigned int i = 0; i < 100000; i++) { for (unsigned int j = 0; j < key_size; j++) { buffer[j] = R_TLB[(rand() % 16)]; @@ -377,7 +363,7 @@ TEST(HandleTrieTest, hasher) { baseline[s] = 0; } baseline[s] = baseline[s] + 1; - value = (TestValue *) trie->lookup(s); + value = (TestValue*) trie->lookup(s); if (value == NULL) { value = new TestValue(); trie->insert(s, value); @@ -386,7 +372,7 @@ TEST(HandleTrieTest, hasher) { } } for (auto const& pair : baseline) { - value = (TestValue *) trie->lookup(pair.first); + value = (TestValue*) trie->lookup(pair.first); EXPECT_EQ(pair.second, value->count); } delete trie; @@ -396,13 +382,13 @@ TEST(HandleTrieTest, hasher) { TEST(HandleTrieTest, benchmark) { char buffer[1000]; map baseline; - TestValue *value; + TestValue* value; StopWatch timer_std; StopWatch timer_trie; unsigned int n_insertions = 1000000; timer_std.start(); - for (unsigned int key_count: {1, 2, 5}) { + for (unsigned int key_count : {1, 2, 5}) { unsigned int key_size = (HANDLE_HASH_SIZE - 1) * key_count; for (unsigned int i = 0; i < n_insertions; i++) { for (unsigned int j = 0; j < key_size; j++) { @@ -419,16 +405,16 @@ TEST(HandleTrieTest, benchmark) { timer_std.stop(); timer_trie.start(); - for (unsigned int key_count: {1, 2, 5}) { + for (unsigned int key_count : {1, 2, 5}) { unsigned int key_size = (HANDLE_HASH_SIZE - 1) * key_count; - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); for (unsigned int i = 0; i < n_insertions; i++) { for (unsigned int j = 0; j < key_size; j++) { buffer[j] = R_TLB[(rand() % 16)]; } buffer[key_size] = 0; string s = buffer; - value = (TestValue *) trie->lookup(s); + value = (TestValue*) trie->lookup(s); if (value == NULL) { value = new TestValue(); trie->insert(s, value); @@ -442,12 +428,12 @@ TEST(HandleTrieTest, benchmark) { cout << "stdlib: " + timer_std.str_time() << endl; cout << "trie: " + timer_trie.str_time() << endl; cout << "=======================================================" << endl; - //EXPECT_EQ(true, false); + // EXPECT_EQ(true, false); } -void producer(HandleTrie *trie, unsigned int n_insertions) { +void producer(HandleTrie* trie, unsigned int n_insertions) { char buffer[1000]; - AccumulatorValue *value; + AccumulatorValue* value; unsigned int key_size = HANDLE_HASH_SIZE - 1; for (unsigned int i = 0; i < n_insertions; i++) { for (unsigned int j = 0; j < key_size; j++) { @@ -460,7 +446,7 @@ void producer(HandleTrie *trie, unsigned int n_insertions) { } } -void visitor(HandleTrie *trie, unsigned int n_visits) { +void visitor(HandleTrie* trie, unsigned int n_visits) { char buffer[1000]; unsigned int key_size = HANDLE_HASH_SIZE - 1; for (unsigned int i = 0; i < n_visits; i++) { @@ -473,8 +459,8 @@ void visitor(HandleTrie *trie, unsigned int n_visits) { } } -void producer2(HandleTrie *trie, unsigned int n_insertions, string *handles) { - AccumulatorValue *value; +void producer2(HandleTrie* trie, unsigned int n_insertions, string* handles) { + AccumulatorValue* value; for (unsigned int i = 0; i < n_insertions; i++) { string s = handles[rand() % HANDLE_SPACE_SIZE]; value = new AccumulatorValue(); @@ -482,7 +468,7 @@ void producer2(HandleTrie *trie, unsigned int n_insertions, string *handles) { } } -void visitor2(HandleTrie *trie, unsigned int n_visits, string *handles) { +void visitor2(HandleTrie* trie, unsigned int n_visits, string* handles) { for (unsigned int i = 0; i < n_visits; i++) { string s = handles[rand() % HANDLE_SPACE_SIZE]; trie->lookup(s); @@ -490,16 +476,16 @@ void visitor2(HandleTrie *trie, unsigned int n_visits, string *handles) { } TEST(HandleTrieTest, multithread) { - vector producers; - vector visitors; + vector producers; + vector visitors; unsigned int n_insertions = 10000; unsigned int n_visits = 10000; StopWatch timer; timer.start(); - for (int n_producers: {2, 10, 100}) { - for (int n_visitors: {2, 10, 100}) { + for (int n_producers : {2, 10, 100}) { + for (int n_visitors : {2, 10, 100}) { unsigned int key_size = HANDLE_HASH_SIZE - 1; - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); producers.clear(); visitors.clear(); for (int i = 0; i < n_producers; i++) { @@ -508,10 +494,10 @@ TEST(HandleTrieTest, multithread) { for (int i = 0; i < n_visitors; i++) { visitors.push_back(new thread(&visitor, trie, n_visits)); } - for (thread *t: producers) { + for (thread* t : producers) { t->join(); } - for (thread *t: visitors) { + for (thread* t : visitors) { t->join(); } delete trie; @@ -525,24 +511,24 @@ TEST(HandleTrieTest, multithread_limited_handle_set) { for (unsigned int i = 0; i < HANDLE_SPACE_SIZE; i++) { handles[i] = random_handle(); } - vector producers; - vector visitors; + vector producers; + vector visitors; unsigned int n_insertions = 100000; unsigned int n_visits = 100000; - for (int n_producers: {2, 10, 100}) { - for (int n_visitors: {2, 10, 100}) { + for (int n_producers : {2, 10, 100}) { + for (int n_visitors : {2, 10, 100}) { unsigned int key_size = HANDLE_HASH_SIZE - 1; - HandleTrie *trie = new HandleTrie(key_size); + HandleTrie* trie = new HandleTrie(key_size); for (int i = 0; i < n_producers; i++) { producers.push_back(new thread(&producer2, trie, n_insertions, handles)); } for (int i = 0; i < n_visitors; i++) { visitors.push_back(new thread(&visitor2, trie, n_visits, handles)); } - for (thread *t: producers) { + for (thread* t : producers) { t->join(); } - for (thread *t: visitors) { + for (thread* t : visitors) { t->join(); } delete trie; diff --git a/src/tests/cpp/handles_answer_test.cc b/src/tests/cpp/handles_answer_test.cc index 6ef09f4..5203855 100644 --- a/src/tests/cpp/handles_answer_test.cc +++ b/src/tests/cpp/handles_answer_test.cc @@ -1,16 +1,15 @@ #include #include -#include "gtest/gtest.h" #include "HandlesAnswer.h" #include "Utils.h" +#include "gtest/gtest.h" #include "test_utils.h" using namespace query_engine; using namespace commons; TEST(HandlesAnswer, assignments_basics) { - Assignment mapping0; // Tests assign() @@ -78,7 +77,6 @@ TEST(HandlesAnswer, assignments_basics) { } TEST(HandlesAnswer, handles_answer_basics) { - // Tests add_handle() HandlesAnswer query_answer1("h1", 0); query_answer1.assignment.assign("v1", "1"); @@ -103,7 +101,7 @@ TEST(HandlesAnswer, handles_answer_basics) { EXPECT_TRUE(query_answer2.assignment.assign("v3", "x")); // Tests copy() - HandlesAnswer *query_answer3 = HandlesAnswer::copy(&query_answer2); + HandlesAnswer* query_answer3 = HandlesAnswer::copy(&query_answer2); EXPECT_EQ(query_answer3->handles_size, 3); EXPECT_TRUE(strcmp(query_answer3->handles[0], "h2") == 0); EXPECT_TRUE(strcmp(query_answer3->handles[1], "hx") == 0); @@ -114,13 +112,12 @@ TEST(HandlesAnswer, handles_answer_basics) { EXPECT_TRUE(query_answer3->assignment.assign("v4", "x")); } -void query_answers_equal(HandlesAnswer *qa1, HandlesAnswer *qa2) { +void query_answers_equal(HandlesAnswer* qa1, HandlesAnswer* qa2) { EXPECT_TRUE(double_equals(qa1->importance, qa2->importance)); EXPECT_EQ(qa1->to_string(), qa2->to_string()); } TEST(HandlesAnswer, tokenization) { - unsigned int NUM_TESTS = 100000; unsigned int MAX_HANDLES = 5; unsigned int MAX_ASSIGNMENTS = 10; @@ -134,9 +131,8 @@ TEST(HandlesAnswer, tokenization) { } unsigned int label_count = 0; for (unsigned int i = 0; i < num_assignments; i++) { - input.assignment.assign( - strdup(sequential_label(label_count).c_str()), - strdup(random_handle().c_str())); + input.assignment.assign(strdup(sequential_label(label_count).c_str()), + strdup(random_handle().c_str())); } query_answers_equal(&input, HandlesAnswer::copy(&input)); diff --git a/src/tests/cpp/hebbian_network_test.cc b/src/tests/cpp/hebbian_network_test.cc index 5f5518c..de2ee16 100644 --- a/src/tests/cpp/hebbian_network_test.cc +++ b/src/tests/cpp/hebbian_network_test.cc @@ -1,20 +1,19 @@ #include #include -#include -#include #include +#include +#include -#include "gtest/gtest.h" -#include "Utils.h" -#include "test_utils.h" #include "HebbianNetwork.h" +#include "Utils.h" #include "expression_hasher.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace attention_broker_server; using namespace commons; TEST(HebbianNetwork, basics) { - HebbianNetwork network; string h1 = prefixed_random_handle("a"); @@ -23,10 +22,10 @@ TEST(HebbianNetwork, basics) { string h4 = prefixed_random_handle("d"); string h5 = prefixed_random_handle("e"); - HebbianNetwork::Node *n1 = network.add_node(h1); - HebbianNetwork::Node *n2 = network.add_node(h2); - HebbianNetwork::Node *n3 = network.add_node(h3); - HebbianNetwork::Node *n4 = network.add_node(h4); + HebbianNetwork::Node* n1 = network.add_node(h1); + HebbianNetwork::Node* n2 = network.add_node(h2); + HebbianNetwork::Node* n3 = network.add_node(h3); + HebbianNetwork::Node* n4 = network.add_node(h4); EXPECT_TRUE(network.get_node_count(h1) == 1); EXPECT_TRUE(network.get_node_count(h2) == 1); @@ -52,7 +51,6 @@ TEST(HebbianNetwork, basics) { } TEST(HebbianNetwork, stress) { - HebbianNetwork network; StopWatch timer_insertion; StopWatch timer_lookup; @@ -61,7 +59,7 @@ TEST(HebbianNetwork, stress) { unsigned int num_insertions = (handle_space_size * 2) * (handle_space_size * 2); unsigned int num_lookups = 10 * num_insertions; - string *handles = build_handle_space(handle_space_size); + string* handles = build_handle_space(handle_space_size); timer_insertion.start(); timer_total.start(); @@ -69,8 +67,8 @@ TEST(HebbianNetwork, stress) { for (unsigned int i = 0; i < num_insertions; i++) { string h1 = handles[rand() % handle_space_size]; string h2 = handles[rand() % handle_space_size]; - HebbianNetwork::Node *n1 = network.add_node(h1); - HebbianNetwork::Node *n2 = network.add_node(h2); + HebbianNetwork::Node* n1 = network.add_node(h1); + HebbianNetwork::Node* n2 = network.add_node(h2); network.add_symmetric_edge(h1, h2, n1, n2); } @@ -93,7 +91,7 @@ TEST(HebbianNetwork, stress) { cout << "Lookups: " << timer_lookup.str_time() << endl; cout << "Total: " << timer_total.str_time() << endl; cout << "==================================================================" << endl; - //EXPECT_TRUE(false); + // EXPECT_TRUE(false); } TEST(HebbianNetwork, alienate_tokens) { @@ -103,22 +101,20 @@ TEST(HebbianNetwork, alienate_tokens) { EXPECT_TRUE(network.alienate_tokens() == 0.0); } -bool visit1(HandleTrie::TrieNode *node, void *data) { - ((HebbianNetwork::Node *) node->value)->importance = 1.0; +bool visit1(HandleTrie::TrieNode* node, void* data) { + ((HebbianNetwork::Node*) node->value)->importance = 1.0; return false; } -bool visit2( - HandleTrie::TrieNode *node, - HebbianNetwork::Node *source, - forward_list &targets, - unsigned int targets_size, - ImportanceType sum_weights, - void *data) { - - unsigned int fan_max = *((unsigned int *) data); +bool visit2(HandleTrie::TrieNode* node, + HebbianNetwork::Node* source, + forward_list& targets, + unsigned int targets_size, + ImportanceType sum_weights, + void* data) { + unsigned int fan_max = *((unsigned int*) data); double stimulus = 1.0 / (double) fan_max; - for (auto target: targets) { + for (auto target : targets) { target->importance += stimulus; source->importance -= stimulus; } diff --git a/src/tests/cpp/hebbian_network_updater_test.cc b/src/tests/cpp/hebbian_network_updater_test.cc index 5fd4db7..1201753 100644 --- a/src/tests/cpp/hebbian_network_updater_test.cc +++ b/src/tests/cpp/hebbian_network_updater_test.cc @@ -1,23 +1,23 @@ -#include #include +#include -#include "gtest/gtest.h" -#include "common.pb.h" +#include "HebbianNetwork.h" +#include "HebbianNetworkUpdater.h" #include "attention_broker.grpc.pb.h" #include "attention_broker.pb.h" -#include "test_utils.h" +#include "common.pb.h" #include "expression_hasher.h" -#include "HebbianNetwork.h" -#include "HebbianNetworkUpdater.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace attention_broker_server; TEST(HebbianNetworkUpdater, correlation) { - string *handles = build_handle_space(6); - HebbianNetwork *network = new HebbianNetwork(); - dasproto::HandleList *request; - ExactCountHebbianUpdater *updater = \ - (ExactCountHebbianUpdater *) HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); + string* handles = build_handle_space(6); + HebbianNetwork* network = new HebbianNetwork(); + dasproto::HandleList* request; + ExactCountHebbianUpdater* updater = (ExactCountHebbianUpdater*) HebbianNetworkUpdater::factory( + HebbianNetworkUpdaterType::EXACT_COUNT); request = new dasproto::HandleList(); request->set_hebbian_network((unsigned long) network); diff --git a/src/tests/cpp/iterator_test.cc b/src/tests/cpp/iterator_test.cc index c7ed714..a1806ea 100644 --- a/src/tests/cpp/iterator_test.cc +++ b/src/tests/cpp/iterator_test.cc @@ -1,22 +1,21 @@ +#include "Iterator.h" + #include -#include "gtest/gtest.h" -#include "QueryNode.h" -#include "LinkTemplate.h" #include "AtomDBSingleton.h" -#include "test_utils.h" -#include "Iterator.h" #include "HandlesAnswer.h" +#include "LinkTemplate.h" +#include "QueryNode.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace query_engine; using namespace query_element; using namespace query_node; class TestQueryElement : public QueryElement { - public: - TestQueryElement(const string &id) { - this->id = id; - } + public: + TestQueryElement(const string& id) { this->id = id; } void setup_buffers() {} void graceful_shutdown() {} }; @@ -31,7 +30,7 @@ TEST(Iterator, basics) { EXPECT_FALSE(query_answer_iterator.finished()); - HandlesAnswer *qa; + HandlesAnswer* qa; HandlesAnswer qa0("h0", 0.0); HandlesAnswer qa1("h1", 0.1); HandlesAnswer qa2("h2", 0.2); @@ -70,7 +69,6 @@ TEST(Iterator, basics) { } TEST(Iterator, link_template_integration) { - setenv("DAS_REDIS_HOSTNAME", "localhost", 1); setenv("DAS_REDIS_PORT", "29000", 1); setenv("DAS_USE_REDIS_CLUSTER", "false", 1); @@ -92,18 +90,18 @@ TEST(Iterator, link_template_integration) { LinkTemplate<3> link_template("Expression", {&similarity, &human, &v1}); Iterator query_answer_iterator(&link_template); - string monkey_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"monkey\"")); - string chimp_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"chimp\"")); - string ent_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"ent\"")); + string monkey_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"monkey\"")); + string chimp_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"chimp\"")); + string ent_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"ent\"")); bool monkey_flag = false; bool chimp_flag = false; bool ent_flag = false; - HandlesAnswer *query_answer; - while (! query_answer_iterator.finished()) { + HandlesAnswer* query_answer; + while (!query_answer_iterator.finished()) { query_answer = dynamic_cast(query_answer_iterator.pop()); if (query_answer != NULL) { string var = string(query_answer->assignment.get("v1")); - //EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); + // EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); if (var == monkey_handle) { // TODO: perform extra checks monkey_flag = true; diff --git a/src/tests/cpp/leadership_broker_test.cc b/src/tests/cpp/leadership_broker_test.cc index 811fa15..0244a59 100644 --- a/src/tests/cpp/leadership_broker_test.cc +++ b/src/tests/cpp/leadership_broker_test.cc @@ -1,18 +1,17 @@ -#include #include +#include -#include "gtest/gtest.h" #include "LeadershipBroker.h" +#include "gtest/gtest.h" using namespace distributed_algorithm_node; TEST(LeadershipBroker, basics) { - try { LeadershipBroker::factory((LeadershipBrokerType) -1); FAIL() << "Expected exception"; - } catch(std::runtime_error const &error) { - } catch(...) { + } catch (std::runtime_error const& error) { + } catch (...) { FAIL() << "Expected std::runtime_error"; } diff --git a/src/tests/cpp/link_creation_agent_test.cc b/src/tests/cpp/link_creation_agent_test.cc index a243905..18d178c 100644 --- a/src/tests/cpp/link_creation_agent_test.cc +++ b/src/tests/cpp/link_creation_agent_test.cc @@ -1,10 +1,11 @@ +#include "link_creation_agent.h" + #include #include #include #include -#include "link_creation_agent.h" #include "link_create_template.h" using namespace std; @@ -113,13 +114,17 @@ vector split(const string& s, char delimiter) { } TEST(LinkCreateTemplate, TestLinkCreateTemplate) { - /** #NOTE Different from the original string test, the to_string() method is not returning the same - order as the input string. to_string is placing the custom fields after the targets + /** #NOTE Different from the original string test, the to_string() method is + not returning the same order as the input string. to_string is placing the + custom fields after the targets */ string link_template_str = - "LINK_CREATE Similarity 3 1 VARIABLE V1 LINK_CREATE Test 3 0 NODE Symbol A VARIABLE V2 " - "LINK_CREATE Test2 1 1 NODE Symbol C CUSTOM_FIELD inter 1 inter_name inter_value NODE Symbol B " - "CUSTOM_FIELD truth_value 2 CUSTOM_FIELD mean 2 count 10 avg 0.9 confidence 0.9"; + "LINK_CREATE Similarity 3 1 VARIABLE V1 " + "LINK_CREATE Test 3 0 NODE Symbol A VARIABLE V2 " + "LINK_CREATE Test2 1 1 NODE Symbol C CUSTOM_FIELD " + "inter 1 inter_name inter_value NODE Symbol B " + "CUSTOM_FIELD truth_value 2 CUSTOM_FIELD mean 2 " + "count 10 avg 0.9 confidence 0.9"; auto link_template = split(link_template_str, ' '); LinkCreateTemplate lct(link_template); EXPECT_EQ(lct.get_link_type(), "Similarity"); @@ -128,7 +133,8 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE I 3 0 VARIABLE V1 LINK_CREATE Test 3 0 NODE Symbol A VARIABLE V2 LINK_CREATE Test2 " + "LINK_CREATE I 3 0 VARIABLE V1 LINK_CREATE Test 3 0 NODE " + "Symbol A VARIABLE V2 LINK_CREATE Test2 " "1 0 NODE Symbol C NODE Symbol B"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct2(link_template); @@ -140,7 +146,8 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE Similarity 2 1 VARIABLE V1 VARIABLE V2 CUSTOM_FIELD truth_value 2 CUSTOM_FIELD " + "LINK_CREATE Similarity 2 1 VARIABLE V1 VARIABLE V2 " + "CUSTOM_FIELD truth_value 2 CUSTOM_FIELD " "mean 2 count 10 avg 0.9 confidence 0.9"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct3(link_template); @@ -150,7 +157,8 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE link_type 2 1 NODE type1 value1 VARIABLE var1 CUSTOM_FIELD field1 1 value1 value2"; + "LINK_CREATE link_type 2 1 NODE type1 value1 VARIABLE " + "var1 CUSTOM_FIELD field1 1 value1 value2"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct4(link_template); EXPECT_EQ(lct4.get_link_type(), "link_type"); @@ -159,14 +167,17 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE TestLink 4 1 NODE NodeType1 Value1 VARIABLE Var1 CUSTOM_FIELD Field1 2 valuename1 " + "LINK_CREATE TestLink 4 1 NODE NodeType1 Value1 VARIABLE Var1 " + "CUSTOM_FIELD Field1 2 valuename1 " "Value1 valuename2 Value2 NODE NodeType2 Value2 VARIABLE Var2"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct5(link_template); EXPECT_EQ(lct5.get_link_type(), "TestLink"); EXPECT_EQ(lct5.to_string(), - "LINK_CREATE TestLink 4 1 NODE NodeType1 Value1 VARIABLE Var1 NODE NodeType2 Value2 " - "VARIABLE Var2 CUSTOM_FIELD Field1 2 valuename1 Value1 valuename2 Value2"); + "LINK_CREATE TestLink 4 1 NODE NodeType1 Value1 " + "VARIABLE Var1 NODE NodeType2 Value2 " + "VARIABLE Var2 CUSTOM_FIELD Field1 2 valuename1 " + "Value1 valuename2 Value2"); EXPECT_EQ(lct5.get_targets().size(), 4); EXPECT_EQ(get(lct5.get_targets()[0]).type, "NodeType1"); EXPECT_EQ(get(lct5.get_targets()[0]).value, "Value1"); @@ -175,7 +186,8 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE AnotherLink 2 1 VARIABLE VarA NODE NodeTypeA ValueA CUSTOM_FIELD FieldA 1 NameA " + "LINK_CREATE AnotherLink 2 1 VARIABLE VarA NODE " + "NodeTypeA ValueA CUSTOM_FIELD FieldA 1 NameA " "ValueA"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct6(link_template); @@ -195,13 +207,15 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template_str.clear(); link_template_str = - "LINK_CREATE ComplexLink 4 2 NODE Type1 Val1 VARIABLE Var1 CUSTOM_FIELD Field1 2 N1 Val1 N2 " + "LINK_CREATE ComplexLink 4 2 NODE Type1 Val1 VARIABLE Var1 CUSTOM_FIELD " + "Field1 2 N1 Val1 N2 " "Val2 NODE Type2 Val2 VARIABLE Var2 CUSTOM_FIELD Field2 1 N3 Val3"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct7(link_template); EXPECT_EQ(lct7.get_link_type(), "ComplexLink"); EXPECT_EQ(lct7.to_string(), - "LINK_CREATE ComplexLink 4 2 NODE Type1 Val1 VARIABLE Var1 NODE Type2 Val2 VARIABLE Var2 " + "LINK_CREATE ComplexLink 4 2 NODE Type1 Val1 VARIABLE Var1 NODE Type2 " + "Val2 VARIABLE Var2 " "CUSTOM_FIELD Field1 2 N1 Val1 N2 Val2 CUSTOM_FIELD Field2 1 N3 Val3"); EXPECT_EQ(lct7.get_targets().size(), 4); EXPECT_EQ(get(lct7.get_targets()[0]).type, "Type1"); @@ -223,7 +237,9 @@ TEST(LinkCreateTemplate, TestLinkCreateTemplate) { link_template.clear(); link_template_str.clear(); - link_template_str = "LINK_CREATE SimpleLink 2 0 VARIABLE SimpleVar NODE SimpleNode SimpleValue"; + link_template_str = + "LINK_CREATE SimpleLink 2 0 VARIABLE SimpleVar NODE " + "SimpleNode SimpleValue"; link_template = split(link_template_str, ' '); LinkCreateTemplate lct8(link_template); EXPECT_EQ(lct8.get_link_type(), "SimpleLink"); @@ -250,7 +266,8 @@ TEST(LinkCreateTemplate, TestInvalidTargetCount) { TEST(LinkCreateTemplate, TestInvalidCustomField) { string link_template_str = - "LINK_CREATE Similarity 2 1 VARIABLE V1 NODE Symbol A CUSTOM_FIELD field1"; + "LINK_CREATE Similarity 2 1 VARIABLE V1 NODE " + "Symbol A CUSTOM_FIELD field1"; auto link_template = split(link_template_str, ' '); EXPECT_THROW(LinkCreateTemplate lct(link_template), invalid_argument); } @@ -267,7 +284,6 @@ TEST(LinkCreateTemplate, TestInvalidNode) { EXPECT_THROW(LinkCreateTemplate lct(link_template), invalid_argument); } - TEST(Link, TestLink) { vector link_template = split("LINK_CREATE Similarity 2 0 VARIABLE V1 VARIABLE V2", ' '); HandlesAnswer* query_answer = new HandlesAnswer(); diff --git a/src/tests/cpp/link_template_test.cc b/src/tests/cpp/link_template_test.cc index fa670a8..27d119e 100644 --- a/src/tests/cpp/link_template_test.cc +++ b/src/tests/cpp/link_template_test.cc @@ -1,17 +1,16 @@ #include -#include "gtest/gtest.h" -#include "QueryNode.h" -#include "LinkTemplate.h" #include "AtomDBSingleton.h" -#include "test_utils.h" #include "HandlesAnswer.h" +#include "LinkTemplate.h" +#include "QueryNode.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace query_engine; using namespace query_element; TEST(LinkTemplate, basics) { - setenv("DAS_REDIS_HOSTNAME", "localhost", 1); setenv("DAS_REDIS_PORT", "29000", 1); setenv("DAS_USE_REDIS_CLUSTER", "false", 1); @@ -36,19 +35,19 @@ TEST(LinkTemplate, basics) { LinkTemplate<3> link_template1("Expression", {&similarity, &human, &v1}); link_template1.subsequent_id = server_node_id; link_template1.setup_buffers(); - //link_template1.fetch_links(); + // link_template1.fetch_links(); Utils::sleep(1000); - string monkey_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"monkey\"")); - string chimp_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"chimp\"")); - string ent_handle = string(terminal_hash((char *) symbol.c_str(), (char *) "\"ent\"")); + string monkey_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"monkey\"")); + string chimp_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"chimp\"")); + string ent_handle = string(terminal_hash((char*) symbol.c_str(), (char*) "\"ent\"")); bool monkey_flag = false; bool chimp_flag = false; bool ent_flag = false; - HandlesAnswer *query_answer; + HandlesAnswer* query_answer; while ((query_answer = dynamic_cast(server_node.pop_query_answer())) != NULL) { string var = string(query_answer->assignment.get("v1")); - //EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); + // EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); if (var == monkey_handle) { // TODO: perform extra checks monkey_flag = true; diff --git a/src/tests/cpp/message_broker_test.cc b/src/tests/cpp/message_broker_test.cc index eec7c09..369ca96 100644 --- a/src/tests/cpp/message_broker_test.cc +++ b/src/tests/cpp/message_broker_test.cc @@ -1,21 +1,20 @@ -#include "gtest/gtest.h" #include "MessageBroker.h" +#include "gtest/gtest.h" using namespace distributed_algorithm_node; class MessageFactoryTest : public MessageFactory { - shared_ptr message_factory(string &command, vector &args) { + shared_ptr message_factory(string& command, vector& args) { return shared_ptr{}; } }; TEST(MessageBroker, basics) { - try { MessageBroker::factory((MessageBrokerType) -1, NULL, ""); FAIL() << "Expected exception"; - } catch(std::runtime_error const &error) { - } catch(...) { + } catch (std::runtime_error const& error) { + } catch (...) { FAIL() << "Expected std::runtime_error"; } @@ -23,8 +22,8 @@ TEST(MessageBroker, basics) { shared_ptr message_broker_ram = MessageBroker::factory(MessageBrokerType::RAM, shared_ptr{}, ""); FAIL() << "Expected exception"; - } catch(std::runtime_error const &error) { - } catch(...) { + } catch (std::runtime_error const& error) { + } catch (...) { FAIL() << "Expected std::runtime_error"; } @@ -32,14 +31,14 @@ TEST(MessageBroker, basics) { shared_ptr message_broke_grpc = MessageBroker::factory(MessageBrokerType::GRPC, shared_ptr{}, ""); FAIL() << "Expected exception"; - } catch(std::runtime_error const &error) { - } catch(...) { + } catch (std::runtime_error const& error) { + } catch (...) { FAIL() << "Expected std::runtime_error"; } - shared_ptr message_broker_ram = - MessageBroker::factory(MessageBrokerType::RAM, shared_ptr(new MessageFactoryTest()), ""); + shared_ptr message_broker_ram = MessageBroker::factory( + MessageBrokerType::RAM, shared_ptr(new MessageFactoryTest()), ""); - shared_ptr message_broker_grpc = - MessageBroker::factory(MessageBrokerType::GRPC, shared_ptr(new MessageFactoryTest()), ""); + shared_ptr message_broker_grpc = MessageBroker::factory( + MessageBrokerType::GRPC, shared_ptr(new MessageFactoryTest()), ""); } diff --git a/src/tests/cpp/nested_link_template_test.cc b/src/tests/cpp/nested_link_template_test.cc index 0beff33..5d147f5 100644 --- a/src/tests/cpp/nested_link_template_test.cc +++ b/src/tests/cpp/nested_link_template_test.cc @@ -1,18 +1,17 @@ #include -#include "gtest/gtest.h" -#include "QueryNode.h" #include "AtomDB.h" -#include "LinkTemplate.h" #include "AtomDBSingleton.h" -#include "test_utils.h" #include "HandlesAnswer.h" +#include "LinkTemplate.h" +#include "QueryNode.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace query_engine; using namespace query_element; TEST(LinkTemplate, basics) { - setenv("DAS_REDIS_HOSTNAME", "localhost", 1); setenv("DAS_REDIS_PORT", "29000", 1); setenv("DAS_USE_REDIS_CLUSTER", "false", 1); @@ -36,9 +35,9 @@ TEST(LinkTemplate, basics) { Iterator iterator(&outter_template); - HandlesAnswer *query_answer; + HandlesAnswer* query_answer; unsigned int count = 0; - while (! iterator.finished()) { + while (!iterator.finished()) { if ((query_answer = dynamic_cast(iterator.pop())) == NULL) { Utils::sleep(); } else { @@ -50,7 +49,6 @@ TEST(LinkTemplate, basics) { } TEST(LinkTemplate, nested_variables) { - string expression = "Expression"; string symbol = "Symbol"; @@ -68,13 +66,13 @@ TEST(LinkTemplate, nested_variables) { Iterator iterator(&and_operator); - HandlesAnswer *query_answer; + HandlesAnswer* query_answer; unsigned int count = 0; - while (! iterator.finished()) { + while (!iterator.finished()) { if ((query_answer = dynamic_cast(iterator.pop())) == NULL) { Utils::sleep(); } else { - //EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); + // EXPECT_TRUE(double_equals(query_answer->importance, 0.0)); count++; } } diff --git a/src/tests/cpp/query_node_test.cc b/src/tests/cpp/query_node_test.cc index c3c308e..60931c1 100644 --- a/src/tests/cpp/query_node_test.cc +++ b/src/tests/cpp/query_node_test.cc @@ -1,14 +1,12 @@ -#include "gtest/gtest.h" - -#include "Utils.h" -#include "QueryNode.h" #include "HandlesAnswer.h" +#include "QueryNode.h" +#include "Utils.h" +#include "gtest/gtest.h" using namespace commons; using namespace query_node; TEST(QueryNode, basics) { - string server_id = "server"; string client1_id = "client1"; string client2_id = "client2"; @@ -24,15 +22,15 @@ TEST(QueryNode, basics) { EXPECT_TRUE(client2.is_query_answers_empty()); EXPECT_FALSE(client2.is_query_answers_finished()); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 0); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 0); - client1.add_query_answer((QueryAnswer *) 1); - client1.add_query_answer((QueryAnswer *) 2); + client1.add_query_answer((QueryAnswer*) 1); + client1.add_query_answer((QueryAnswer*) 2); Utils::sleep(1000); - client2.add_query_answer((QueryAnswer *) 3); - client2.add_query_answer((QueryAnswer *) 4); + client2.add_query_answer((QueryAnswer*) 3); + client2.add_query_answer((QueryAnswer*) 4); Utils::sleep(1000); - client1.add_query_answer((QueryAnswer *) 5); + client1.add_query_answer((QueryAnswer*) 5); Utils::sleep(1000); EXPECT_FALSE(server.is_query_answers_empty()); @@ -53,12 +51,12 @@ TEST(QueryNode, basics) { EXPECT_TRUE(client2.is_query_answers_empty()); EXPECT_TRUE(client2.is_query_answers_finished()); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 1); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 2); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 3); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 4); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 5); - ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer *) 0); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 1); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 2); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 3); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 4); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 5); + ASSERT_TRUE(server.pop_query_answer() == (QueryAnswer*) 0); EXPECT_TRUE(server.is_query_answers_empty()); EXPECT_TRUE(server.is_query_answers_finished()); diff --git a/src/tests/cpp/request_selector_test.cc b/src/tests/cpp/request_selector_test.cc index 2376d5d..e04d39b 100644 --- a/src/tests/cpp/request_selector_test.cc +++ b/src/tests/cpp/request_selector_test.cc @@ -1,36 +1,26 @@ -#include "gtest/gtest.h" - -#include "Utils.h" -#include "SharedQueue.h" #include "RequestSelector.h" +#include "SharedQueue.h" +#include "Utils.h" +#include "gtest/gtest.h" using namespace attention_broker_server; class TestMessage { - public: - int message; - TestMessage(int n) { - message = n; - } + public: + int message; + TestMessage(int n) { message = n; } }; TEST(RequestSelectorTest, even_thread_count) { - - SharedQueue *stimulus = new SharedQueue(1); - SharedQueue *correlation = new SharedQueue(1); + SharedQueue* stimulus = new SharedQueue(1); + SharedQueue* correlation = new SharedQueue(1); - RequestSelector *selector0 = RequestSelector::factory( - SelectorType::EVEN_THREAD_COUNT, - 0, - stimulus, - correlation); - RequestSelector *selector1 = RequestSelector::factory( - SelectorType::EVEN_THREAD_COUNT, - 1, - stimulus, - correlation); + RequestSelector* selector0 = + RequestSelector::factory(SelectorType::EVEN_THREAD_COUNT, 0, stimulus, correlation); + RequestSelector* selector1 = + RequestSelector::factory(SelectorType::EVEN_THREAD_COUNT, 1, stimulus, correlation); - pair request; + pair request; for (int i = 0; i < 1000; i++) { if (Utils::flip_coin()) { request = selector0->next(); diff --git a/src/tests/cpp/shared_queue_test.cc b/src/tests/cpp/shared_queue_test.cc index 651e37d..b9f670c 100644 --- a/src/tests/cpp/shared_queue_test.cc +++ b/src/tests/cpp/shared_queue_test.cc @@ -1,74 +1,63 @@ -#include "gtest/gtest.h" - #include "AttentionBrokerServer.h" +#include "gtest/gtest.h" using namespace attention_broker_server; -class TestSharedQueue: public SharedQueue { - public: - TestSharedQueue(unsigned int n) : SharedQueue(n) { - } - unsigned int test_current_size() { - return current_size(); - } - unsigned int test_current_start() { - return current_start(); - } - unsigned int test_current_end() { - return current_end(); - } +class TestSharedQueue : public SharedQueue { + public: + TestSharedQueue(unsigned int n) : SharedQueue(n) {} + unsigned int test_current_size() { return current_size(); } + unsigned int test_current_start() { return current_start(); } + unsigned int test_current_end() { return current_end(); } }; class TestMessage { - public: - int message; - TestMessage(int n) { - message = n; - } + public: + int message; + TestMessage(int n) { message = n; } }; TEST(SharedQueueTest, basics) { - dasproto::Empty empty; dasproto::Ack ack; TestSharedQueue q1((unsigned int) 5); EXPECT_TRUE(q1.test_current_size() == 5); - q1.enqueue((void *) "1"); - EXPECT_EQ((char *) q1.dequeue(), "1"); - q1.enqueue((void *) "2"); - q1.enqueue((void *) "3"); - q1.enqueue((void *) "4"); - q1.enqueue((void *) "5"); + q1.enqueue((void*) "1"); + EXPECT_EQ((char*) q1.dequeue(), "1"); + q1.enqueue((void*) "2"); + q1.enqueue((void*) "3"); + q1.enqueue((void*) "4"); + q1.enqueue((void*) "5"); EXPECT_TRUE(q1.test_current_size() == 5); - EXPECT_EQ((char *) q1.dequeue(), "2"); - q1.enqueue((void *) "6"); - q1.enqueue((void *) "7"); + EXPECT_EQ((char*) q1.dequeue(), "2"); + q1.enqueue((void*) "6"); + q1.enqueue((void*) "7"); EXPECT_TRUE(q1.test_current_size() == 5); - EXPECT_EQ((char *) q1.dequeue(), "3"); - q1.enqueue((void *) "8"); - EXPECT_EQ((char *) q1.dequeue(), "4"); - q1.enqueue((void *) "9"); - EXPECT_EQ((char *) q1.dequeue(), "5"); - q1.enqueue((void *) "10"); + EXPECT_EQ((char*) q1.dequeue(), "3"); + q1.enqueue((void*) "8"); + EXPECT_EQ((char*) q1.dequeue(), "4"); + q1.enqueue((void*) "9"); + EXPECT_EQ((char*) q1.dequeue(), "5"); + q1.enqueue((void*) "10"); EXPECT_TRUE(q1.test_current_size() == 5); - EXPECT_EQ((char *) q1.dequeue(), "6"); - EXPECT_EQ((char *) q1.dequeue(), "7"); - q1.enqueue((void *) "11"); - q1.enqueue((void *) "12"); + EXPECT_EQ((char*) q1.dequeue(), "6"); + EXPECT_EQ((char*) q1.dequeue(), "7"); + q1.enqueue((void*) "11"); + q1.enqueue((void*) "12"); EXPECT_TRUE(q1.test_current_size() == 5); EXPECT_TRUE(q1.test_current_start() == 2); EXPECT_TRUE(q1.test_current_end() == 2); - q1.enqueue((void *) "13"); + q1.enqueue((void*) "13"); EXPECT_TRUE(q1.test_current_size() == 10); EXPECT_TRUE(q1.test_current_start() == 0); EXPECT_TRUE(q1.test_current_end() == 6); - q1.enqueue((void *) "14"); - EXPECT_EQ((char *) q1.dequeue(), "8"); - EXPECT_EQ((char *) q1.dequeue(), "9"); - EXPECT_EQ((char *) q1.dequeue(), "10"); - EXPECT_EQ((char *) q1.dequeue(), "11"); - EXPECT_EQ((char *) q1.dequeue(), "12"); - EXPECT_EQ((char *) q1.dequeue(), "13"); - EXPECT_EQ((char *) q1.dequeue(), "14"); + q1.enqueue((void*) "14"); + EXPECT_EQ((char*) q1.dequeue(), "8"); + EXPECT_EQ((char*) q1.dequeue(), "9"); + EXPECT_EQ((char*) q1.dequeue(), "10"); + EXPECT_EQ((char*) q1.dequeue(), "11"); + EXPECT_EQ((char*) q1.dequeue(), "12"); + EXPECT_EQ((char*) q1.dequeue(), "13"); + EXPECT_EQ((char*) q1.dequeue(), "14"); } diff --git a/src/tests/cpp/stimulus_spreader_test.cc b/src/tests/cpp/stimulus_spreader_test.cc index 6e99f89..5b2b778 100644 --- a/src/tests/cpp/stimulus_spreader_test.cc +++ b/src/tests/cpp/stimulus_spreader_test.cc @@ -1,16 +1,16 @@ -#include #include +#include -#include "gtest/gtest.h" -#include "common.pb.h" -#include "attention_broker.grpc.pb.h" -#include "attention_broker.pb.h" -#include "test_utils.h" -#include "expression_hasher.h" #include "AttentionBrokerServer.h" #include "HebbianNetwork.h" #include "HebbianNetworkUpdater.h" #include "StimulusSpreader.h" +#include "attention_broker.grpc.pb.h" +#include "attention_broker.pb.h" +#include "common.pb.h" +#include "expression_hasher.h" +#include "gtest/gtest.h" +#include "test_utils.h" using namespace attention_broker_server; @@ -20,18 +20,17 @@ bool importance_equals(ImportanceType importance, double v2) { } TEST(TokenSpreader, distribute_wages) { - unsigned int num_tests = 10000; unsigned int total_nodes = 100; - TokenSpreader *spreader; + TokenSpreader* spreader; ImportanceType tokens_to_spread; - dasproto::HandleCount *request; + dasproto::HandleCount* request; TokenSpreader::StimuliData data; for (unsigned int i = 0; i < num_tests; i++) { - string *handles = build_handle_space(total_nodes); - spreader = (TokenSpreader *) StimulusSpreader::factory(StimulusSpreaderType::TOKEN); + string* handles = build_handle_space(total_nodes); + spreader = (TokenSpreader*) StimulusSpreader::factory(StimulusSpreaderType::TOKEN); tokens_to_spread = 1.0; request = new dasproto::HandleCount(); @@ -44,11 +43,21 @@ TEST(TokenSpreader, distribute_wages) { data.importance_changes = new HandleTrie(HANDLE_HASH_SIZE - 1); spreader->distribute_wages(request, tokens_to_spread, &data); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[0]))->wages, 0.250)); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[1]))->wages, 0.125)); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[2]))->wages, 0.250)); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[3]))->wages, 0.125)); - EXPECT_TRUE(importance_equals(((TokenSpreader::ImportanceChanges *) data.importance_changes->lookup(handles[4]))->wages, 0.250)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[0]))->wages, + 0.250)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[1]))->wages, + 0.125)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[2]))->wages, + 0.250)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[3]))->wages, + 0.125)); + EXPECT_TRUE(importance_equals( + ((TokenSpreader::ImportanceChanges*) data.importance_changes->lookup(handles[4]))->wages, + 0.250)); EXPECT_TRUE(data.importance_changes->lookup(handles[5]) == NULL); EXPECT_TRUE(data.importance_changes->lookup(handles[6]) == NULL); EXPECT_TRUE(data.importance_changes->lookup(handles[7]) == NULL); @@ -59,12 +68,11 @@ TEST(TokenSpreader, distribute_wages) { } } -static HebbianNetwork *build_test_network(string *handles) { - - HebbianNetwork *network = new HebbianNetwork(); - dasproto::HandleList *request; - ExactCountHebbianUpdater *updater = \ - (ExactCountHebbianUpdater *) HebbianNetworkUpdater::factory(HebbianNetworkUpdaterType::EXACT_COUNT); +static HebbianNetwork* build_test_network(string* handles) { + HebbianNetwork* network = new HebbianNetwork(); + dasproto::HandleList* request; + ExactCountHebbianUpdater* updater = (ExactCountHebbianUpdater*) HebbianNetworkUpdater::factory( + HebbianNetworkUpdaterType::EXACT_COUNT); request = new dasproto::HandleList(); request->set_hebbian_network((unsigned long) network); @@ -86,7 +94,6 @@ static HebbianNetwork *build_test_network(string *handles) { } TEST(TokenSpreader, spread_stimuli) { - // -------------------------------------------------------------------- // NOTE TO REVIEWER: I left debug messages because this code extremely // error prone and difficult to debug. Probably we'll @@ -95,12 +102,12 @@ TEST(TokenSpreader, spread_stimuli) { // -------------------------------------------------------------------- // Build and check network - string *handles = build_handle_space(6, true); + string* handles = build_handle_space(6, true); for (unsigned int i = 0; i < 6; i++) { cout << i << ": " << handles[i] << endl; } - HebbianNetwork *network = build_test_network(handles); + HebbianNetwork* network = build_test_network(handles); unsigned int expected[6][6] = { {0, 1, 1, 1, 0, 0}, @@ -118,7 +125,8 @@ TEST(TokenSpreader, spread_stimuli) { EXPECT_TRUE(network->get_node_count(handles[i]) == 1); } for (unsigned int j = 0; j < 6; j++) { - cout << i << ", " << j << ": " << expected[i][j] << " " << network->get_asymmetric_edge_count(handles[i], handles[j]) << endl; + cout << i << ", " << j << ": " << expected[i][j] << " " + << network->get_asymmetric_edge_count(handles[i], handles[j]) << endl; EXPECT_TRUE(network->get_asymmetric_edge_count(handles[i], handles[j]) == expected[i][j]); } } @@ -126,9 +134,8 @@ TEST(TokenSpreader, spread_stimuli) { // ---------------------------------------------------------- // Build and process simulus spreading request - dasproto::HandleCount *request; - TokenSpreader *spreader = \ - (TokenSpreader *) StimulusSpreader::factory(StimulusSpreaderType::TOKEN); + dasproto::HandleCount* request; + TokenSpreader* spreader = (TokenSpreader*) StimulusSpreader::factory(StimulusSpreaderType::TOKEN); request = new dasproto::HandleCount(); request->set_hebbian_network((unsigned long) network); diff --git a/src/tests/cpp/test_utils.cc b/src/tests/cpp/test_utils.cc index 4c734e9..54f01df 100644 --- a/src/tests/cpp/test_utils.cc +++ b/src/tests/cpp/test_utils.cc @@ -1,9 +1,11 @@ -#include "expression_hasher.h" -#include "Utils.h" #include "test_utils.h" + #include #include +#include "Utils.h" +#include "expression_hasher.h" + static char REVERSE_TLB[16] = { '0', '1', @@ -23,9 +25,7 @@ static char REVERSE_TLB[16] = { 'f', }; -double random_importance() { - return ((double) rand()) / RAND_MAX; -} +double random_importance() { return ((double) rand()) / RAND_MAX; } string random_handle() { char buffer[HANDLE_HASH_SIZE]; @@ -38,9 +38,7 @@ string random_handle() { return s; } -string sequential_label(unsigned int &count, string prefix) { - return prefix + std::to_string(count++); -} +string sequential_label(unsigned int& count, string prefix) { return prefix + std::to_string(count++); } string prefixed_random_handle(string prefix) { char buffer[HANDLE_HASH_SIZE]; @@ -57,12 +55,10 @@ string prefixed_random_handle(string prefix) { return s; } -static bool str_comp(string &a, string &b) { - return a.compare(b) < 0; -} +static bool str_comp(string& a, string& b) { return a.compare(b) < 0; } -string *build_handle_space(unsigned int size, bool sort) { - string *answer = new string[size]; +string* build_handle_space(unsigned int size, bool sort) { + string* answer = new string[size]; for (unsigned int i = 0; i < size; i++) { answer[i] = random_handle(); } @@ -72,6 +68,4 @@ string *build_handle_space(unsigned int size, bool sort) { return answer; } -bool double_equals(double v1, double v2) { - return fabs(v2 - v1) < 0.001; -} +bool double_equals(double v1, double v2) { return fabs(v2 - v1) < 0.001; } diff --git a/src/tests/cpp/test_utils.h b/src/tests/cpp/test_utils.h index 2ba9d15..6705323 100644 --- a/src/tests/cpp/test_utils.h +++ b/src/tests/cpp/test_utils.h @@ -1,16 +1,17 @@ #ifndef _ATTENTION_BROKER_SERVER_TESTS_TESTUTILS #define _ATTENTION_BROKER_SERVER_TESTS_TESTUTILS -#include #include +#include + using namespace std; double random_importance(); string random_handle(); -string sequential_label(unsigned int &count, string prefix = "v"); +string sequential_label(unsigned int& count, string prefix = "v"); string prefixed_random_handle(string prefix); -string *build_handle_space(unsigned int size, bool sort=false); +string* build_handle_space(unsigned int size, bool sort = false); bool double_equals(double v1, double v2); #endif diff --git a/src/tests/cpp/worker_threads_test.cc b/src/tests/cpp/worker_threads_test.cc index e850b89..ec8f7f7 100644 --- a/src/tests/cpp/worker_threads_test.cc +++ b/src/tests/cpp/worker_threads_test.cc @@ -1,41 +1,35 @@ #include #include -#include "gtest/gtest.h" -#include "common.pb.h" +#include "HebbianNetwork.h" +#include "SharedQueue.h" +#include "Utils.h" +#include "WorkerThreads.h" #include "attention_broker.grpc.pb.h" #include "attention_broker.pb.h" - -#include "Utils.h" +#include "common.pb.h" +#include "gtest/gtest.h" #include "test_utils.h" -#include "SharedQueue.h" -#include "WorkerThreads.h" -#include "HebbianNetwork.h" using namespace attention_broker_server; -class TestSharedQueue: public SharedQueue { - public: - TestSharedQueue() : SharedQueue() { - } - unsigned int test_current_count() { - return current_count(); - } +class TestSharedQueue : public SharedQueue { + public: + TestSharedQueue() : SharedQueue() {} + unsigned int test_current_count() { return current_count(); } }; - TEST(WorkerThreads, basics) { - - dasproto::HandleCount *handle_count; - dasproto::HandleList *handle_list; + dasproto::HandleCount* handle_count; + dasproto::HandleList* handle_list; unsigned int num_requests = 1000000; unsigned int wait_for_threads_ms = 500; - for (double stimulus_prob: {0.0, 0.25, 0.5, 0.75, 1.0}) { - TestSharedQueue *stimulus = new TestSharedQueue(); - TestSharedQueue *correlation = new TestSharedQueue(); - WorkerThreads *pool = new WorkerThreads(stimulus, correlation); + for (double stimulus_prob : {0.0, 0.25, 0.5, 0.75, 1.0}) { + TestSharedQueue* stimulus = new TestSharedQueue(); + TestSharedQueue* correlation = new TestSharedQueue(); + WorkerThreads* pool = new WorkerThreads(stimulus, correlation); for (unsigned int i = 0; i < num_requests; i++) { if (Utils::flip_coin(stimulus_prob)) { handle_count = new dasproto::HandleCount(); @@ -57,15 +51,14 @@ TEST(WorkerThreads, basics) { } TEST(WorkerThreads, hebbian_network_updater_basics) { - - dasproto::HandleList *handle_list; + dasproto::HandleList* handle_list; map node_count; map edge_count; HebbianNetwork network; - TestSharedQueue *stimulus = new TestSharedQueue(); - TestSharedQueue *correlation = new TestSharedQueue(); - WorkerThreads *pool = new WorkerThreads(stimulus, correlation); + TestSharedQueue* stimulus = new TestSharedQueue(); + TestSharedQueue* correlation = new TestSharedQueue(); + WorkerThreads* pool = new WorkerThreads(stimulus, correlation); handle_list = new dasproto::HandleList(); string h1 = random_handle(); @@ -146,25 +139,23 @@ TEST(WorkerThreads, hebbian_network_updater_basics) { } TEST(WorkerThreads, hebbian_network_updater_stress) { - - #define HANDLE_SPACE_SIZE ((unsigned int) 100) +#define HANDLE_SPACE_SIZE ((unsigned int) 100) unsigned int num_requests = 10; unsigned int max_handles_per_request = 10; unsigned int wait_for_worker_threads_ms = 3000; - - dasproto::HandleList *handle_list; + dasproto::HandleList* handle_list; string handles[HANDLE_SPACE_SIZE]; map node_count; map edge_count; - HebbianNetwork *network = new HebbianNetwork(); + HebbianNetwork* network = new HebbianNetwork(); for (unsigned int i = 0; i < HANDLE_SPACE_SIZE; i++) { handles[i] = random_handle(); } - TestSharedQueue *stimulus = new TestSharedQueue(); - TestSharedQueue *correlation = new TestSharedQueue(); - WorkerThreads *pool = new WorkerThreads(stimulus, correlation); + TestSharedQueue* stimulus = new TestSharedQueue(); + TestSharedQueue* correlation = new TestSharedQueue(); + WorkerThreads* pool = new WorkerThreads(stimulus, correlation); for (unsigned int i = 0; i < num_requests; i++) { handle_list = new dasproto::HandleList(); unsigned int num_handles = (rand() % (max_handles_per_request - 1)) + 2; @@ -176,8 +167,8 @@ TEST(WorkerThreads, hebbian_network_updater_stress) { } node_count[h] = node_count[h] + 1; } - for (const string &h1: handle_list->list()) { - for (const string &h2: handle_list->list()) { + for (const string& h1 : handle_list->list()) { + for (const string& h2 : handle_list->list()) { string composite; if (h1.compare(h2) < 0) { composite = h1 + h2; diff --git a/src/tools/format/BUILD.bazel b/src/tools/format/BUILD.bazel index 08f130f..5f45186 100644 --- a/src/tools/format/BUILD.bazel +++ b/src/tools/format/BUILD.bazel @@ -3,11 +3,14 @@ load("@aspect_rules_lint//format:defs.bzl", "format_multirun") format_multirun( name = "format", - # cc = "@llvm_toolchain_llvm//:bin/clang-format", + cc = "@llvm_toolchain_llvm//:bin/clang-format", python = "@aspect_rules_lint//format:ruff", - disable_git_attribute_checks=True, - # starlark = "@buildifier_prebuild//:buildifier" # TODO: ADD rules for yaml, markdown, rust, c + # starlark = "@buildifier_prebuild//:buildifier" + # rust = "@rules_rust//tools/upstream_wrapper:rustfmt", + # yaml = "@aspect_rules_lint//format:yamlfmt", + + disable_git_attribute_checks=True, visibility = ["//visibility:public"], ) diff --git a/src/tools/lint/BUILD b/src/tools/lint/BUILD index e69de29..89c2d01 100644 --- a/src/tools/lint/BUILD +++ b/src/tools/lint/BUILD @@ -0,0 +1,14 @@ +load("@bazel_skylib//rules:native_binary.bzl", "native_binary") + +native_binary( + name = "clang_tidy", + src = select( + { + "@bazel_tools//src/conditions:linux_x86_64": "@llvm_toolchain_llvm//:bin/clang-tidy", + "@bazel_tools//src/conditions:linux_aarch64": "@llvm_toolchain_llvm//:bin/clang-tidy", + "@bazel_tools//src/conditions:darwin_x86_64": "@llvm_toolchain_llvm//:bin/clang-tidy", + "@bazel_tools//src/conditions:darwin_arm64": "@llvm_toolchain_llvm//:bin/clang-tidy", + }, + ), + out = "clang_tidy", +) diff --git a/src/tools/lint/linters.bzl b/src/tools/lint/linters.bzl index 2265c8b..4acfadb 100644 --- a/src/tools/lint/linters.bzl +++ b/src/tools/lint/linters.bzl @@ -1,6 +1,17 @@ load("@aspect_rules_lint//lint:lint_test.bzl", "lint_test") +load("@aspect_rules_lint//lint:clang_tidy.bzl", "lint_clang_tidy_aspect") load("@aspect_rules_lint//lint:ruff.bzl", "lint_ruff_aspect") +clang_tidy = lint_clang_tidy_aspect( + binary = "@@//tools/lint:clang_tidy", + global_config = "@@//:.clang-tidy", + lint_target_headers = True, + angle_includes_are_system = False, + verbose = False, +) + +clang_tidy_test = lint_test(aspect = clang_tidy) + ruff = lint_ruff_aspect( binary = "@multitool//tools/ruff", configs = [ From c2879ce204751400cbd21c091747e4033ac90b71 Mon Sep 17 00:00:00 2001 From: Pedro Costa Date: Fri, 21 Feb 2025 20:02:33 +0000 Subject: [PATCH 5/5] revert: changes to clang-format --- .clang-format | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index cb6fd0c..eac44b1 100644 --- a/.clang-format +++ b/.clang-format @@ -212,9 +212,9 @@ StatementAttributeLikeMacros: StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION -TabWidth: 8 +TabWidth: 4 UseCRLF: false -UseTab: Always +UseTab: Never WhitespaceSensitiveMacros: - STRINGIZE - PP_STRINGIZE