Skip to content

Commit

Permalink
[DXFC-407] Add a TimeSeriesSubscriptionSymbol and IndexedEventSubscri…
Browse files Browse the repository at this point in the history
…ptionSymbol support (#14)
  • Loading branch information
AnatolyKalin committed Jun 20, 2023
1 parent 999b1f6 commit bc02427
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 34 deletions.
1 change: 1 addition & 0 deletions include/dxfeed_graal_cpp_api/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "api/DXEndpoint.hpp"
#include "api/DXFeed.hpp"
#include "api/DXFeedSubscription.hpp"
#include "api/FilteredSubscriptionSymbol.hpp"
#include "api/osub/IndexedEventSubscriptionSymbol.hpp"
#include "api/osub/TimeSeriesSubscriptionSymbol.hpp"
#include "api/osub/WildcardSymbol.hpp"
Expand Down
28 changes: 28 additions & 0 deletions include/dxfeed_graal_cpp_api/api/FilteredSubscriptionSymbol.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2023 Devexperts LLC.
// SPDX-License-Identifier: MPL-2.0

#pragma once

#include "../internal/Conf.hpp"

namespace dxfcpp {

/**
* This marker interface marks subscription symbol classes (like TimeSeriesSubscriptionSymbol)
* that attach "filters" to the actual symbols. Filtered subscription symbols implement their `operator ==`
* and `std::hash<>` based on their symbol only, without considering their "filter" part (for example, a TimeSeriesSubscriptionSymbol has
* a @ref TimeSeriesSubscriptionSymbol::getFromTime() "fromTime" filter on a time range of events).
*
* <p>DXFeedSubscription has the following behavior for filtered symbols. There can be only one
* active filter per symbol. Adding new filtered symbol with the same symbol but different filter
* removes the old one from subscription, adds the new one, and <em>notifies</em>
* ObservableSubscriptionChangeListener <em>about this subscription change</em>.
* The later is a special behaviour for filtered subscription symbols, because on other types of
* symbols (like StringSymbol, for example) there is no notification when replacing one symbol with the other that
* is "equal" to the first one.
*/
struct FilteredSubscriptionSymbol {

};

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct SymbolWrapper;
* Indexed event subscription symbols are compared based on their @ref ::getEventSymbol() "eventSymbol" and
* @ref ::getSource() "source".
*/
class DXFCPP_EXPORT IndexedEventSubscriptionSymbol final {
class DXFCPP_EXPORT IndexedEventSubscriptionSymbol {
std::unique_ptr<SymbolWrapper> eventSymbol_;
IndexedEventSource source_;

Expand All @@ -59,16 +59,16 @@ class DXFCPP_EXPORT IndexedEventSubscriptionSymbol final {
*
* @return the wrapped event symbol.
*/
const std::unique_ptr<SymbolWrapper> &getEventSymbol() const;
virtual const std::unique_ptr<SymbolWrapper> &getEventSymbol() const;

/**
* Returns indexed event source.
*
* @return indexed event source.
*/
const IndexedEventSource &getSource() const;
virtual const IndexedEventSource &getSource() const;

void *toGraal() const noexcept;
virtual void *toGraal() const noexcept;

static void freeGraal(void* graal) noexcept;

Expand All @@ -79,7 +79,7 @@ class DXFCPP_EXPORT IndexedEventSubscriptionSymbol final {
*
* @return string representation of this indexed event subscription symbol.
*/
std::string toString() const noexcept;
virtual std::string toString() const noexcept;

bool operator==(const IndexedEventSubscriptionSymbol &indexedEventSubscriptionSymbol) const noexcept;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "../../internal/Conf.hpp"

#include "../../symbols/SymbolWrapper.hpp"
#include "../FilteredSubscriptionSymbol.hpp"

#include <cstdint>
#include <memory>
Expand All @@ -14,6 +15,7 @@
namespace dxfcpp {

struct SymbolWrapper;
class IndexedEventSubscriptionSymbol;

/**
* Represents subscription to time-series of events.
Expand All @@ -36,8 +38,8 @@ struct SymbolWrapper;
* It means, that a set of time-series subscription symbols can contain at most one time-series subscription
* for each event symbol.
*/
class DXFCPP_EXPORT TimeSeriesSubscriptionSymbol final {
std::unique_ptr<SymbolWrapper> eventSymbol_;
class DXFCPP_EXPORT TimeSeriesSubscriptionSymbol final : public IndexedEventSubscriptionSymbol,
public FilteredSubscriptionSymbol {
std::int64_t fromTime_;

public:
Expand All @@ -55,21 +57,14 @@ class DXFCPP_EXPORT TimeSeriesSubscriptionSymbol final {
TimeSeriesSubscriptionSymbol() noexcept = default;
virtual ~TimeSeriesSubscriptionSymbol() noexcept = default;

/**
* Returns the wrapped event symbol (CandleSymbol, WildcardSymbol, etc).
*
* @return the wrapped event symbol.
*/
const std::unique_ptr<SymbolWrapper> &getEventSymbol() const;

/**
* Returns the subscription time.
*
* @return the subscription time.
*/
std::int64_t getFromTime() const;

void *toGraal() const noexcept;
void *toGraal() const noexcept override;

static void freeGraal(void *graal) noexcept;

Expand All @@ -80,7 +75,7 @@ class DXFCPP_EXPORT TimeSeriesSubscriptionSymbol final {
*
* @return string representation of this time-series subscription symbol.
*/
std::string toString() const noexcept;
std::string toString() const noexcept override;

bool operator==(const TimeSeriesSubscriptionSymbol &timeSeriesSubscriptionSymbol) const noexcept;

Expand Down
1 change: 1 addition & 0 deletions include/dxfeed_graal_cpp_api/api/osub/WildcardSymbol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <cstdint>
#include <memory>
#include <utility>
#include <string>

namespace dxfcpp {

Expand Down
8 changes: 8 additions & 0 deletions src/api/osub/IndexedEventSubscriptionSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ IndexedEventSubscriptionSymbol::IndexedEventSubscriptionSymbol(

IndexedEventSubscriptionSymbol &IndexedEventSubscriptionSymbol::operator=(
const IndexedEventSubscriptionSymbol &indexedEventSubscriptionSymbol) noexcept {
if (this == &indexedEventSubscriptionSymbol) {
return *this;
}

eventSymbol_ = std::make_unique<SymbolWrapper>(*indexedEventSubscriptionSymbol.eventSymbol_);
source_ = indexedEventSubscriptionSymbol.source_;

Expand All @@ -103,6 +107,10 @@ IndexedEventSubscriptionSymbol &IndexedEventSubscriptionSymbol::operator=(

IndexedEventSubscriptionSymbol &
IndexedEventSubscriptionSymbol::operator=(IndexedEventSubscriptionSymbol &&indexedEventSubscriptionSymbol) noexcept {
if (this == &indexedEventSubscriptionSymbol) {
return *this;
}

eventSymbol_ = std::move(indexedEventSubscriptionSymbol.eventSymbol_);
source_ = indexedEventSubscriptionSymbol.source_;

Expand Down
39 changes: 21 additions & 18 deletions src/api/osub/TimeSeriesSubscriptionSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
namespace dxfcpp {

TimeSeriesSubscriptionSymbol::TimeSeriesSubscriptionSymbol(const SymbolWrapper &eventSymbol, int64_t fromTime) noexcept
: eventSymbol_(std::make_unique<SymbolWrapper>(eventSymbol)), fromTime_(fromTime) {}

const std::unique_ptr<SymbolWrapper> &TimeSeriesSubscriptionSymbol::getEventSymbol() const { return eventSymbol_; }
: IndexedEventSubscriptionSymbol(eventSymbol, IndexedEventSource::DEFAULT), fromTime_(fromTime) {}

int64_t TimeSeriesSubscriptionSymbol::getFromTime() const { return fromTime_; }

Expand All @@ -21,7 +19,7 @@ void *TimeSeriesSubscriptionSymbol::toGraal() const noexcept {
}

auto *graalSymbol = new (std::nothrow) dxfg_time_series_subscription_symbol_t{
{TIME_SERIES_SUBSCRIPTION}, dxfcpp::bit_cast<dxfg_symbol_t *>(eventSymbol_->toGraal()), fromTime_};
{TIME_SERIES_SUBSCRIPTION}, dxfcpp::bit_cast<dxfg_symbol_t *>(getEventSymbol()->toGraal()), fromTime_};

return dxfcpp::bit_cast<void *>(graalSymbol);
}
Expand Down Expand Up @@ -58,46 +56,51 @@ TimeSeriesSubscriptionSymbol TimeSeriesSubscriptionSymbol::fromGraal(void *graal

std::string TimeSeriesSubscriptionSymbol::toString() const noexcept {
if constexpr (Debugger::isDebug) {
return "TimeSeriesSubscriptionSymbol{" + eventSymbol_->toString() +
return "TimeSeriesSubscriptionSymbol{" + getEventSymbol()->toString() +
", fromTime = " + formatTimeStampWithMillis(fromTime_) + "}";
} else {
return eventSymbol_->toString() + "{fromTime=" + formatTimeStampWithMillis(fromTime_) + "}";
return getEventSymbol()->toString() + "{fromTime=" + formatTimeStampWithMillis(fromTime_) + "}";
}
}

bool TimeSeriesSubscriptionSymbol::operator==(
const TimeSeriesSubscriptionSymbol &timeSeriesSubscriptionSymbol) const noexcept {
return *eventSymbol_ == *timeSeriesSubscriptionSymbol.eventSymbol_;
return *getEventSymbol() == *timeSeriesSubscriptionSymbol.getEventSymbol();
}

bool TimeSeriesSubscriptionSymbol::operator<(
const TimeSeriesSubscriptionSymbol &timeSeriesSubscriptionSymbol) const noexcept {
return *eventSymbol_ < *timeSeriesSubscriptionSymbol.eventSymbol_;
return *getEventSymbol() < *timeSeriesSubscriptionSymbol.getEventSymbol();
}

TimeSeriesSubscriptionSymbol::TimeSeriesSubscriptionSymbol(
const TimeSeriesSubscriptionSymbol &timeSeriesSubscriptionSymbol) noexcept {
eventSymbol_ = std::make_unique<SymbolWrapper>(*timeSeriesSubscriptionSymbol.eventSymbol_);
fromTime_ = timeSeriesSubscriptionSymbol.fromTime_;
}
const TimeSeriesSubscriptionSymbol &timeSeriesSubscriptionSymbol) noexcept
: IndexedEventSubscriptionSymbol(timeSeriesSubscriptionSymbol), fromTime_{timeSeriesSubscriptionSymbol.fromTime_} {}

TimeSeriesSubscriptionSymbol::TimeSeriesSubscriptionSymbol(
TimeSeriesSubscriptionSymbol &&timeSeriesSubscriptionSymbol) noexcept {
eventSymbol_ = std::move(timeSeriesSubscriptionSymbol.eventSymbol_);
fromTime_ = timeSeriesSubscriptionSymbol.fromTime_;
}
TimeSeriesSubscriptionSymbol &&timeSeriesSubscriptionSymbol) noexcept
: IndexedEventSubscriptionSymbol(std::move(timeSeriesSubscriptionSymbol)),
fromTime_{timeSeriesSubscriptionSymbol.fromTime_} {}

TimeSeriesSubscriptionSymbol &
TimeSeriesSubscriptionSymbol::operator=(const TimeSeriesSubscriptionSymbol &timeSeriesSubscriptionSymbol) noexcept {
eventSymbol_ = std::make_unique<SymbolWrapper>(*timeSeriesSubscriptionSymbol.eventSymbol_);
if (this == &timeSeriesSubscriptionSymbol) {
return *this;
}

IndexedEventSubscriptionSymbol::operator=(timeSeriesSubscriptionSymbol);
fromTime_ = timeSeriesSubscriptionSymbol.fromTime_;

return *this;
}

TimeSeriesSubscriptionSymbol &
TimeSeriesSubscriptionSymbol::operator=(TimeSeriesSubscriptionSymbol &&timeSeriesSubscriptionSymbol) noexcept {
eventSymbol_ = std::move(timeSeriesSubscriptionSymbol.eventSymbol_);
if (this == &timeSeriesSubscriptionSymbol) {
return *this;
}

IndexedEventSubscriptionSymbol::operator=(std::move(timeSeriesSubscriptionSymbol));
fromTime_ = timeSeriesSubscriptionSymbol.fromTime_;

return *this;
Expand Down

0 comments on commit bc02427

Please sign in to comment.