opengris-scaler 1.12.7__cp38-cp38-manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opengris-scaler might be problematic. Click here for more details.
- opengris_scaler-1.12.7.dist-info/METADATA +729 -0
- opengris_scaler-1.12.7.dist-info/RECORD +232 -0
- opengris_scaler-1.12.7.dist-info/WHEEL +5 -0
- opengris_scaler-1.12.7.dist-info/entry_points.txt +9 -0
- opengris_scaler-1.12.7.dist-info/licenses/LICENSE +201 -0
- opengris_scaler-1.12.7.dist-info/licenses/LICENSE.spdx +7 -0
- opengris_scaler-1.12.7.dist-info/licenses/NOTICE +8 -0
- opengris_scaler.libs/libcapnp-1-b787335c.1.0.so +0 -0
- opengris_scaler.libs/libkj-1-094aa318.1.0.so +0 -0
- scaler/CMakeLists.txt +11 -0
- scaler/__init__.py +14 -0
- scaler/about.py +5 -0
- scaler/client/__init__.py +0 -0
- scaler/client/agent/__init__.py +0 -0
- scaler/client/agent/client_agent.py +210 -0
- scaler/client/agent/disconnect_manager.py +27 -0
- scaler/client/agent/future_manager.py +112 -0
- scaler/client/agent/heartbeat_manager.py +74 -0
- scaler/client/agent/mixins.py +89 -0
- scaler/client/agent/object_manager.py +98 -0
- scaler/client/agent/task_manager.py +64 -0
- scaler/client/client.py +635 -0
- scaler/client/future.py +252 -0
- scaler/client/object_buffer.py +129 -0
- scaler/client/object_reference.py +25 -0
- scaler/client/serializer/__init__.py +0 -0
- scaler/client/serializer/default.py +16 -0
- scaler/client/serializer/mixins.py +38 -0
- scaler/cluster/__init__.py +0 -0
- scaler/cluster/cluster.py +115 -0
- scaler/cluster/combo.py +148 -0
- scaler/cluster/object_storage_server.py +45 -0
- scaler/cluster/scheduler.py +83 -0
- scaler/config/__init__.py +0 -0
- scaler/config/defaults.py +87 -0
- scaler/config/loader.py +95 -0
- scaler/config/mixins.py +15 -0
- scaler/config/section/__init__.py +0 -0
- scaler/config/section/cluster.py +56 -0
- scaler/config/section/native_worker_adapter.py +44 -0
- scaler/config/section/object_storage_server.py +7 -0
- scaler/config/section/scheduler.py +53 -0
- scaler/config/section/symphony_worker_adapter.py +47 -0
- scaler/config/section/top.py +13 -0
- scaler/config/section/webui.py +16 -0
- scaler/config/types/__init__.py +0 -0
- scaler/config/types/object_storage_server.py +45 -0
- scaler/config/types/worker.py +57 -0
- scaler/config/types/zmq.py +79 -0
- scaler/entry_points/__init__.py +0 -0
- scaler/entry_points/cluster.py +133 -0
- scaler/entry_points/object_storage_server.py +41 -0
- scaler/entry_points/scheduler.py +135 -0
- scaler/entry_points/top.py +286 -0
- scaler/entry_points/webui.py +26 -0
- scaler/entry_points/worker_adapter_native.py +137 -0
- scaler/entry_points/worker_adapter_symphony.py +102 -0
- scaler/io/__init__.py +0 -0
- scaler/io/async_binder.py +85 -0
- scaler/io/async_connector.py +95 -0
- scaler/io/async_object_storage_connector.py +185 -0
- scaler/io/mixins.py +154 -0
- scaler/io/sync_connector.py +68 -0
- scaler/io/sync_object_storage_connector.py +185 -0
- scaler/io/sync_subscriber.py +83 -0
- scaler/io/utility.py +31 -0
- scaler/io/ymq/CMakeLists.txt +98 -0
- scaler/io/ymq/__init__.py +0 -0
- scaler/io/ymq/_ymq.pyi +96 -0
- scaler/io/ymq/_ymq.so +0 -0
- scaler/io/ymq/bytes.h +114 -0
- scaler/io/ymq/common.h +29 -0
- scaler/io/ymq/configuration.h +60 -0
- scaler/io/ymq/epoll_context.cpp +185 -0
- scaler/io/ymq/epoll_context.h +85 -0
- scaler/io/ymq/error.h +132 -0
- scaler/io/ymq/event_loop.h +55 -0
- scaler/io/ymq/event_loop_thread.cpp +64 -0
- scaler/io/ymq/event_loop_thread.h +46 -0
- scaler/io/ymq/event_manager.h +81 -0
- scaler/io/ymq/file_descriptor.h +203 -0
- scaler/io/ymq/interruptive_concurrent_queue.h +169 -0
- scaler/io/ymq/io_context.cpp +98 -0
- scaler/io/ymq/io_context.h +44 -0
- scaler/io/ymq/io_socket.cpp +299 -0
- scaler/io/ymq/io_socket.h +121 -0
- scaler/io/ymq/iocp_context.cpp +102 -0
- scaler/io/ymq/iocp_context.h +83 -0
- scaler/io/ymq/logging.h +163 -0
- scaler/io/ymq/message.h +15 -0
- scaler/io/ymq/message_connection.h +16 -0
- scaler/io/ymq/message_connection_tcp.cpp +672 -0
- scaler/io/ymq/message_connection_tcp.h +96 -0
- scaler/io/ymq/network_utils.h +179 -0
- scaler/io/ymq/pymod_ymq/bytes.h +113 -0
- scaler/io/ymq/pymod_ymq/exception.h +124 -0
- scaler/io/ymq/pymod_ymq/gil.h +15 -0
- scaler/io/ymq/pymod_ymq/io_context.h +166 -0
- scaler/io/ymq/pymod_ymq/io_socket.h +285 -0
- scaler/io/ymq/pymod_ymq/message.h +99 -0
- scaler/io/ymq/pymod_ymq/python.h +153 -0
- scaler/io/ymq/pymod_ymq/ymq.cpp +23 -0
- scaler/io/ymq/pymod_ymq/ymq.h +357 -0
- scaler/io/ymq/readme.md +114 -0
- scaler/io/ymq/simple_interface.cpp +80 -0
- scaler/io/ymq/simple_interface.h +24 -0
- scaler/io/ymq/tcp_client.cpp +367 -0
- scaler/io/ymq/tcp_client.h +75 -0
- scaler/io/ymq/tcp_operations.h +41 -0
- scaler/io/ymq/tcp_server.cpp +410 -0
- scaler/io/ymq/tcp_server.h +79 -0
- scaler/io/ymq/third_party/concurrentqueue.h +3747 -0
- scaler/io/ymq/timed_queue.h +272 -0
- scaler/io/ymq/timestamp.h +102 -0
- scaler/io/ymq/typedefs.h +20 -0
- scaler/io/ymq/utils.h +34 -0
- scaler/io/ymq/ymq.py +130 -0
- scaler/object_storage/CMakeLists.txt +50 -0
- scaler/object_storage/__init__.py +0 -0
- scaler/object_storage/constants.h +11 -0
- scaler/object_storage/defs.h +14 -0
- scaler/object_storage/io_helper.cpp +44 -0
- scaler/object_storage/io_helper.h +9 -0
- scaler/object_storage/message.cpp +56 -0
- scaler/object_storage/message.h +130 -0
- scaler/object_storage/object_manager.cpp +126 -0
- scaler/object_storage/object_manager.h +52 -0
- scaler/object_storage/object_storage_server.cpp +359 -0
- scaler/object_storage/object_storage_server.h +126 -0
- scaler/object_storage/object_storage_server.so +0 -0
- scaler/object_storage/pymod_object_storage_server.cpp +104 -0
- scaler/protocol/__init__.py +0 -0
- scaler/protocol/capnp/__init__.py +0 -0
- scaler/protocol/capnp/_python.py +6 -0
- scaler/protocol/capnp/common.capnp +63 -0
- scaler/protocol/capnp/message.capnp +216 -0
- scaler/protocol/capnp/object_storage.capnp +52 -0
- scaler/protocol/capnp/status.capnp +73 -0
- scaler/protocol/introduction.md +105 -0
- scaler/protocol/python/__init__.py +0 -0
- scaler/protocol/python/common.py +135 -0
- scaler/protocol/python/message.py +726 -0
- scaler/protocol/python/mixins.py +13 -0
- scaler/protocol/python/object_storage.py +118 -0
- scaler/protocol/python/status.py +279 -0
- scaler/protocol/worker.md +228 -0
- scaler/scheduler/__init__.py +0 -0
- scaler/scheduler/allocate_policy/__init__.py +0 -0
- scaler/scheduler/allocate_policy/allocate_policy.py +9 -0
- scaler/scheduler/allocate_policy/capability_allocate_policy.py +280 -0
- scaler/scheduler/allocate_policy/even_load_allocate_policy.py +159 -0
- scaler/scheduler/allocate_policy/mixins.py +55 -0
- scaler/scheduler/controllers/__init__.py +0 -0
- scaler/scheduler/controllers/balance_controller.py +65 -0
- scaler/scheduler/controllers/client_controller.py +131 -0
- scaler/scheduler/controllers/config_controller.py +31 -0
- scaler/scheduler/controllers/graph_controller.py +424 -0
- scaler/scheduler/controllers/information_controller.py +81 -0
- scaler/scheduler/controllers/mixins.py +201 -0
- scaler/scheduler/controllers/object_controller.py +147 -0
- scaler/scheduler/controllers/scaling_controller.py +86 -0
- scaler/scheduler/controllers/task_controller.py +373 -0
- scaler/scheduler/controllers/worker_controller.py +168 -0
- scaler/scheduler/object_usage/__init__.py +0 -0
- scaler/scheduler/object_usage/object_tracker.py +131 -0
- scaler/scheduler/scheduler.py +253 -0
- scaler/scheduler/task/__init__.py +0 -0
- scaler/scheduler/task/task_state_machine.py +92 -0
- scaler/scheduler/task/task_state_manager.py +61 -0
- scaler/ui/__init__.py +0 -0
- scaler/ui/constants.py +9 -0
- scaler/ui/live_display.py +118 -0
- scaler/ui/memory_window.py +146 -0
- scaler/ui/setting_page.py +47 -0
- scaler/ui/task_graph.py +370 -0
- scaler/ui/task_log.py +83 -0
- scaler/ui/utility.py +35 -0
- scaler/ui/webui.py +125 -0
- scaler/ui/worker_processors.py +85 -0
- scaler/utility/__init__.py +0 -0
- scaler/utility/debug.py +19 -0
- scaler/utility/event_list.py +63 -0
- scaler/utility/event_loop.py +58 -0
- scaler/utility/exceptions.py +42 -0
- scaler/utility/formatter.py +44 -0
- scaler/utility/graph/__init__.py +0 -0
- scaler/utility/graph/optimization.py +27 -0
- scaler/utility/graph/topological_sorter.py +11 -0
- scaler/utility/graph/topological_sorter_graphblas.py +174 -0
- scaler/utility/identifiers.py +105 -0
- scaler/utility/logging/__init__.py +0 -0
- scaler/utility/logging/decorators.py +25 -0
- scaler/utility/logging/scoped_logger.py +33 -0
- scaler/utility/logging/utility.py +183 -0
- scaler/utility/many_to_many_dict.py +123 -0
- scaler/utility/metadata/__init__.py +0 -0
- scaler/utility/metadata/profile_result.py +31 -0
- scaler/utility/metadata/task_flags.py +30 -0
- scaler/utility/mixins.py +13 -0
- scaler/utility/network_util.py +7 -0
- scaler/utility/one_to_many_dict.py +72 -0
- scaler/utility/queues/__init__.py +0 -0
- scaler/utility/queues/async_indexed_queue.py +37 -0
- scaler/utility/queues/async_priority_queue.py +70 -0
- scaler/utility/queues/async_sorted_priority_queue.py +45 -0
- scaler/utility/queues/indexed_queue.py +114 -0
- scaler/utility/serialization.py +9 -0
- scaler/version.txt +1 -0
- scaler/worker/__init__.py +0 -0
- scaler/worker/agent/__init__.py +0 -0
- scaler/worker/agent/heartbeat_manager.py +107 -0
- scaler/worker/agent/mixins.py +137 -0
- scaler/worker/agent/processor/__init__.py +0 -0
- scaler/worker/agent/processor/object_cache.py +107 -0
- scaler/worker/agent/processor/processor.py +279 -0
- scaler/worker/agent/processor/streaming_buffer.py +28 -0
- scaler/worker/agent/processor_holder.py +145 -0
- scaler/worker/agent/processor_manager.py +365 -0
- scaler/worker/agent/profiling_manager.py +109 -0
- scaler/worker/agent/task_manager.py +150 -0
- scaler/worker/agent/timeout_manager.py +19 -0
- scaler/worker/preload.py +84 -0
- scaler/worker/worker.py +264 -0
- scaler/worker_adapter/__init__.py +0 -0
- scaler/worker_adapter/native.py +154 -0
- scaler/worker_adapter/symphony/__init__.py +0 -0
- scaler/worker_adapter/symphony/callback.py +45 -0
- scaler/worker_adapter/symphony/heartbeat_manager.py +79 -0
- scaler/worker_adapter/symphony/message.py +24 -0
- scaler/worker_adapter/symphony/task_manager.py +288 -0
- scaler/worker_adapter/symphony/worker.py +205 -0
- scaler/worker_adapter/symphony/worker_adapter.py +142 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#include "scaler/object_storage/message.h"
|
|
2
|
+
|
|
3
|
+
namespace scaler {
|
|
4
|
+
namespace object_storage {
|
|
5
|
+
|
|
6
|
+
kj::Array<const capnp::word> ObjectID::toBuffer() const
|
|
7
|
+
{
|
|
8
|
+
capnp::MallocMessageBuilder returnMsg;
|
|
9
|
+
auto objectIDRoot = returnMsg.initRoot<scaler::protocol::ObjectID>();
|
|
10
|
+
|
|
11
|
+
objectIDRoot.setField0(value[0]);
|
|
12
|
+
objectIDRoot.setField1(value[1]);
|
|
13
|
+
objectIDRoot.setField2(value[2]);
|
|
14
|
+
objectIDRoot.setField3(value[3]);
|
|
15
|
+
|
|
16
|
+
return capnp::messageToFlatArray(returnMsg);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
kj::Array<const capnp::word> ObjectRequestHeader::toBuffer() const
|
|
20
|
+
{
|
|
21
|
+
capnp::MallocMessageBuilder returnMsg;
|
|
22
|
+
auto reqRoot = returnMsg.initRoot<scaler::protocol::ObjectRequestHeader>();
|
|
23
|
+
|
|
24
|
+
auto reqRootObjectID = reqRoot.initObjectID();
|
|
25
|
+
reqRootObjectID.setField0(objectID[0]);
|
|
26
|
+
reqRootObjectID.setField1(objectID[1]);
|
|
27
|
+
reqRootObjectID.setField2(objectID[2]);
|
|
28
|
+
reqRootObjectID.setField3(objectID[3]);
|
|
29
|
+
|
|
30
|
+
reqRoot.setPayloadLength(payloadLength);
|
|
31
|
+
reqRoot.setRequestID(requestID);
|
|
32
|
+
reqRoot.setRequestType(requestType);
|
|
33
|
+
|
|
34
|
+
return capnp::messageToFlatArray(returnMsg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
kj::Array<const capnp::word> ObjectResponseHeader::toBuffer() const
|
|
38
|
+
{
|
|
39
|
+
capnp::MallocMessageBuilder returnMsg;
|
|
40
|
+
auto respRoot = returnMsg.initRoot<scaler::protocol::ObjectResponseHeader>();
|
|
41
|
+
|
|
42
|
+
auto respRootObjectID = respRoot.initObjectID();
|
|
43
|
+
respRootObjectID.setField0(objectID[0]);
|
|
44
|
+
respRootObjectID.setField1(objectID[1]);
|
|
45
|
+
respRootObjectID.setField2(objectID[2]);
|
|
46
|
+
respRootObjectID.setField3(objectID[3]);
|
|
47
|
+
|
|
48
|
+
respRoot.setPayloadLength(payloadLength);
|
|
49
|
+
respRoot.setResponseID(responseID);
|
|
50
|
+
respRoot.setResponseType(responseType);
|
|
51
|
+
|
|
52
|
+
return capnp::messageToFlatArray(returnMsg);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}; // namespace object_storage
|
|
56
|
+
}; // namespace scaler
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <capnp/serialize.h>
|
|
4
|
+
|
|
5
|
+
#include <array>
|
|
6
|
+
#include <cstdio>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
#include "../protocol/capnp/object_storage.capnp.h"
|
|
10
|
+
|
|
11
|
+
namespace scaler {
|
|
12
|
+
namespace object_storage {
|
|
13
|
+
|
|
14
|
+
static constexpr size_t CAPNP_HEADER_SIZE = 80;
|
|
15
|
+
static constexpr size_t CAPNP_WORD_SIZE = sizeof(capnp::word);
|
|
16
|
+
|
|
17
|
+
template <typename T>
|
|
18
|
+
concept ObjectStorageMessage = requires(const T obj, std::vector<capnp::word> buffer) {
|
|
19
|
+
{ T::bufferSize() } -> std::same_as<size_t>;
|
|
20
|
+
|
|
21
|
+
{ obj.toBuffer() } -> std::same_as<kj::Array<const capnp::word>>;
|
|
22
|
+
|
|
23
|
+
{ T::fromBuffer(buffer) } -> std::same_as<T>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
struct ObjectID {
|
|
27
|
+
std::array<uint64_t, 4> value;
|
|
28
|
+
|
|
29
|
+
constexpr ObjectID() {};
|
|
30
|
+
|
|
31
|
+
constexpr ObjectID(uint64_t v0, uint64_t v1, uint64_t v2, uint64_t v3): value({v0, v1, v2, v3}) {};
|
|
32
|
+
|
|
33
|
+
constexpr uint64_t& operator[](size_t index) { return value[index]; }
|
|
34
|
+
|
|
35
|
+
constexpr const uint64_t& operator[](size_t index) const { return value[index]; }
|
|
36
|
+
|
|
37
|
+
constexpr std::strong_ordering operator<=>(const ObjectID& other) const = default;
|
|
38
|
+
|
|
39
|
+
static constexpr size_t bufferSize() { return 48; }
|
|
40
|
+
|
|
41
|
+
kj::Array<const capnp::word> toBuffer() const;
|
|
42
|
+
|
|
43
|
+
template <typename Buffer>
|
|
44
|
+
static ObjectID fromBuffer(const Buffer& buffer)
|
|
45
|
+
{
|
|
46
|
+
capnp::FlatArrayMessageReader reader(
|
|
47
|
+
kj::ArrayPtr<const capnp::word>((const capnp::word*)buffer.data(), bufferSize() / CAPNP_WORD_SIZE));
|
|
48
|
+
|
|
49
|
+
auto objectIDRoot = reader.getRoot<scaler::protocol::ObjectID>();
|
|
50
|
+
|
|
51
|
+
return {objectIDRoot.getField0(), objectIDRoot.getField1(), objectIDRoot.getField2(), objectIDRoot.getField3()};
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
static_assert(ObjectStorageMessage<ObjectID>);
|
|
56
|
+
|
|
57
|
+
struct ObjectRequestHeader {
|
|
58
|
+
ObjectID objectID;
|
|
59
|
+
uint64_t payloadLength;
|
|
60
|
+
uint64_t requestID;
|
|
61
|
+
scaler::protocol::ObjectRequestHeader::ObjectRequestType requestType;
|
|
62
|
+
|
|
63
|
+
static constexpr size_t bufferSize() { return CAPNP_HEADER_SIZE; }
|
|
64
|
+
|
|
65
|
+
kj::Array<const capnp::word> toBuffer() const;
|
|
66
|
+
|
|
67
|
+
template <typename Buffer>
|
|
68
|
+
static ObjectRequestHeader fromBuffer(const Buffer& buffer)
|
|
69
|
+
{
|
|
70
|
+
capnp::FlatArrayMessageReader reader(
|
|
71
|
+
kj::ArrayPtr<const capnp::word>((const capnp::word*)buffer.data(), bufferSize() / CAPNP_WORD_SIZE));
|
|
72
|
+
|
|
73
|
+
auto requestRoot = reader.getRoot<scaler::protocol::ObjectRequestHeader>();
|
|
74
|
+
auto objectIDRoot = requestRoot.getObjectID();
|
|
75
|
+
|
|
76
|
+
return ObjectRequestHeader {
|
|
77
|
+
.objectID =
|
|
78
|
+
{
|
|
79
|
+
objectIDRoot.getField0(),
|
|
80
|
+
objectIDRoot.getField1(),
|
|
81
|
+
objectIDRoot.getField2(),
|
|
82
|
+
objectIDRoot.getField3(),
|
|
83
|
+
},
|
|
84
|
+
.payloadLength = requestRoot.getPayloadLength(),
|
|
85
|
+
.requestID = requestRoot.getRequestID(),
|
|
86
|
+
.requestType = requestRoot.getRequestType(),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
static_assert(ObjectStorageMessage<ObjectRequestHeader>);
|
|
92
|
+
|
|
93
|
+
struct ObjectResponseHeader {
|
|
94
|
+
ObjectID objectID;
|
|
95
|
+
uint64_t payloadLength;
|
|
96
|
+
uint64_t responseID;
|
|
97
|
+
scaler::protocol::ObjectResponseHeader::ObjectResponseType responseType;
|
|
98
|
+
|
|
99
|
+
static constexpr size_t bufferSize() { return CAPNP_HEADER_SIZE; }
|
|
100
|
+
|
|
101
|
+
kj::Array<const capnp::word> toBuffer() const;
|
|
102
|
+
|
|
103
|
+
template <typename Buffer>
|
|
104
|
+
static ObjectResponseHeader fromBuffer(const Buffer& buffer)
|
|
105
|
+
{
|
|
106
|
+
capnp::FlatArrayMessageReader reader(
|
|
107
|
+
kj::ArrayPtr<const capnp::word>((const capnp::word*)buffer.data(), bufferSize() / CAPNP_WORD_SIZE));
|
|
108
|
+
|
|
109
|
+
auto responseRoot = reader.getRoot<scaler::protocol::ObjectResponseHeader>();
|
|
110
|
+
auto objectIDRoot = responseRoot.getObjectID();
|
|
111
|
+
|
|
112
|
+
return ObjectResponseHeader {
|
|
113
|
+
.objectID =
|
|
114
|
+
{
|
|
115
|
+
objectIDRoot.getField0(),
|
|
116
|
+
objectIDRoot.getField1(),
|
|
117
|
+
objectIDRoot.getField2(),
|
|
118
|
+
objectIDRoot.getField3(),
|
|
119
|
+
},
|
|
120
|
+
.payloadLength = responseRoot.getPayloadLength(),
|
|
121
|
+
.responseID = responseRoot.getResponseID(),
|
|
122
|
+
.responseType = responseRoot.getResponseType(),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
static_assert(ObjectStorageMessage<ObjectResponseHeader>);
|
|
128
|
+
|
|
129
|
+
}; // namespace object_storage
|
|
130
|
+
}; // namespace scaler
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#include "scaler/object_storage/object_manager.h"
|
|
2
|
+
|
|
3
|
+
#include <algorithm>
|
|
4
|
+
|
|
5
|
+
template <>
|
|
6
|
+
struct std::hash<scaler::object_storage::ObjectPayload> {
|
|
7
|
+
std::size_t operator()(const scaler::object_storage::ObjectPayload& payload) const noexcept
|
|
8
|
+
{
|
|
9
|
+
return std::hash<std::string_view> {}({reinterpret_cast<const char*>(payload.data()), payload.size()});
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
namespace scaler {
|
|
14
|
+
namespace object_storage {
|
|
15
|
+
|
|
16
|
+
ObjectManager::ObjectManager()
|
|
17
|
+
{
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
std::shared_ptr<const ObjectPayload> ObjectManager::setObject(
|
|
21
|
+
const ObjectID& objectID, ObjectPayload&& payload) noexcept
|
|
22
|
+
{
|
|
23
|
+
if (hasObject(objectID)) {
|
|
24
|
+
// Overriding object: delete old first
|
|
25
|
+
deleteObject(objectID);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
ObjectHash hash = std::hash<ObjectPayload> {}(payload);
|
|
29
|
+
|
|
30
|
+
objectIDToHash[objectID] = hash;
|
|
31
|
+
|
|
32
|
+
auto objectIt = hashToObject.find(hash);
|
|
33
|
+
|
|
34
|
+
if (objectIt == hashToObject.end()) {
|
|
35
|
+
// New object payload
|
|
36
|
+
objectIt = hashToObject
|
|
37
|
+
.emplace(
|
|
38
|
+
hash,
|
|
39
|
+
ManagedObject {
|
|
40
|
+
.useCount = 1,
|
|
41
|
+
.payload = std::make_shared<const ObjectPayload>(std::move(payload)),
|
|
42
|
+
})
|
|
43
|
+
.first;
|
|
44
|
+
} else {
|
|
45
|
+
// Known object payload
|
|
46
|
+
++(objectIt->second.useCount);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return objectIt->second.payload;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
std::shared_ptr<const ObjectPayload> ObjectManager::getObject(const ObjectID& objectID) const noexcept
|
|
53
|
+
{
|
|
54
|
+
auto hashIt = objectIDToHash.find(objectID);
|
|
55
|
+
|
|
56
|
+
if (hashIt == objectIDToHash.end()) {
|
|
57
|
+
return SharedObjectPayload(nullptr);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return hashToObject.at(hashIt->second).payload;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
bool ObjectManager::deleteObject(const ObjectID& objectID) noexcept
|
|
64
|
+
{
|
|
65
|
+
auto hashIt = objectIDToHash.find(objectID);
|
|
66
|
+
|
|
67
|
+
if (hashIt == objectIDToHash.end()) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const ObjectHash& hash = hashIt->second;
|
|
72
|
+
|
|
73
|
+
auto objectIt = hashToObject.find(hash);
|
|
74
|
+
|
|
75
|
+
--objectIt->second.useCount;
|
|
76
|
+
if (objectIt->second.useCount < 1) {
|
|
77
|
+
hashToObject.erase(objectIt);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
objectIDToHash.erase(hashIt);
|
|
81
|
+
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
std::shared_ptr<const ObjectPayload> ObjectManager::duplicateObject(
|
|
86
|
+
const ObjectID& originalObjectID, const ObjectID& newObjectID) noexcept
|
|
87
|
+
{
|
|
88
|
+
auto hashIt = objectIDToHash.find(originalObjectID);
|
|
89
|
+
|
|
90
|
+
if (hashIt == objectIDToHash.end()) {
|
|
91
|
+
return nullptr;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (hasObject(newObjectID)) {
|
|
95
|
+
// Overriding object: delete old first
|
|
96
|
+
deleteObject(newObjectID);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
auto hash = hashIt->second;
|
|
100
|
+
|
|
101
|
+
ManagedObject& object = hashToObject[hash];
|
|
102
|
+
|
|
103
|
+
++(object.useCount);
|
|
104
|
+
|
|
105
|
+
objectIDToHash[newObjectID] = hash;
|
|
106
|
+
|
|
107
|
+
return object.payload;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
bool ObjectManager::hasObject(const ObjectID& objectID) const noexcept
|
|
111
|
+
{
|
|
112
|
+
return objectIDToHash.contains(objectID);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
size_t ObjectManager::size() const noexcept
|
|
116
|
+
{
|
|
117
|
+
return objectIDToHash.size();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
size_t ObjectManager::sizeUnique() const noexcept
|
|
121
|
+
{
|
|
122
|
+
return hashToObject.size();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
}; // namespace object_storage
|
|
126
|
+
}; // namespace scaler
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <map>
|
|
4
|
+
#include <memory>
|
|
5
|
+
|
|
6
|
+
#include "scaler/object_storage/defs.h"
|
|
7
|
+
#include "scaler/object_storage/message.h"
|
|
8
|
+
|
|
9
|
+
namespace scaler {
|
|
10
|
+
namespace object_storage {
|
|
11
|
+
|
|
12
|
+
class ObjectManager {
|
|
13
|
+
public:
|
|
14
|
+
ObjectManager();
|
|
15
|
+
|
|
16
|
+
// Returns the pointer to the created (and moved) object.
|
|
17
|
+
std::shared_ptr<const ObjectPayload> setObject(const ObjectID& objectID, ObjectPayload&& payload) noexcept;
|
|
18
|
+
|
|
19
|
+
// Returns `nullptr` if the object does not exist.
|
|
20
|
+
std::shared_ptr<const ObjectPayload> getObject(const ObjectID& objectID) const noexcept;
|
|
21
|
+
|
|
22
|
+
// Returns `true` if the deleted object existed, otherwise returns `false`.
|
|
23
|
+
bool deleteObject(const ObjectID& objectID) noexcept;
|
|
24
|
+
|
|
25
|
+
// Creates a new `ObjectID` referencing the same object's content as `originalObjectID`. Overrides `newObjectID` if
|
|
26
|
+
// it already exist.
|
|
27
|
+
// Returns `nullptr` if `originalObjectID` does not exist, otherwise returns the object's content.
|
|
28
|
+
std::shared_ptr<const ObjectPayload> duplicateObject(
|
|
29
|
+
const ObjectID& originalObjectID, const ObjectID& newObjectID) noexcept;
|
|
30
|
+
|
|
31
|
+
bool hasObject(const ObjectID& objectID) const noexcept;
|
|
32
|
+
|
|
33
|
+
// Returns the total number of objects stored.
|
|
34
|
+
size_t size() const noexcept;
|
|
35
|
+
|
|
36
|
+
// Returns the total number of unique objects stored (i.e. only count duplicate payloads once).
|
|
37
|
+
size_t sizeUnique() const noexcept;
|
|
38
|
+
|
|
39
|
+
private:
|
|
40
|
+
using ObjectHash = std::size_t;
|
|
41
|
+
|
|
42
|
+
struct ManagedObject {
|
|
43
|
+
size_t useCount;
|
|
44
|
+
std::shared_ptr<const ObjectPayload> payload;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
std::map<ObjectID, ObjectHash> objectIDToHash;
|
|
48
|
+
std::map<ObjectHash, ManagedObject> hashToObject;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
}; // namespace object_storage
|
|
52
|
+
}; // namespace scaler
|