diff --git a/course02/homework01/matt/linked_list.cc b/course02/homework01/matt/linked_list.cc index fd976bd..ae1d93e 100644 --- a/course02/homework01/matt/linked_list.cc +++ b/course02/homework01/matt/linked_list.cc @@ -1,4 +1,7 @@ +// Linked List +#include + template LinkedList::LinkedList() {} @@ -28,7 +31,6 @@ void LinkedList::Append(const T& data) if(mFirst==nullptr) { mFirst = std::make_unique>(data); - std::cout << mFirst->mData << std::endl; mLast = mFirst.get(); } else @@ -40,3 +42,50 @@ void LinkedList::Append(const T& data) mSize++; } +//Linked List Iterator + +template +LinkedListIterator LinkedList::begin() +{ + return LinkedListIterator{mFirst.get()}; +} + +template +LinkedListIterator LinkedList::end() +{ + return LinkedListIterator{mLast->mNext.get()}; +} + +template +std::ostream& operator<<(std::ostream& stream, const LinkedList& list) +{ + Node* ptrNode = list.mFirst.get(); + while(ptrNode != nullptr) + { + stream << ptrNode->mData << ", "; + ptrNode = ptrNode->mNext.get(); + } + + return stream; +} + +template +LinkedListIterator::LinkedListIterator(Node* ptrNode) : mPtrNode(ptrNode){} + +template +LinkedListIterator& LinkedListIterator::operator++() +{ + mPtrNode = mPtrNode->mNext.get(); +} + +template +bool LinkedListIterator::operator !=(const LinkedListIterator& other) +{ + return mPtrNode != other.mPtrNode; +} + +template +T& LinkedListIterator::operator*() +{ + return mPtrNode->mData; +} diff --git a/course02/homework01/matt/linked_list.h b/course02/homework01/matt/linked_list.h index 4b439d5..ddec738 100644 --- a/course02/homework01/matt/linked_list.h +++ b/course02/homework01/matt/linked_list.h @@ -11,6 +11,9 @@ struct Node std::unique_ptr> mNext; }; +template +class LinkedListIterator; + template class LinkedList { @@ -24,22 +27,33 @@ class LinkedList void Append(const T& data); - friend std::ostream& operator<<(std::ostream& stream, const LinkedList& list) - { - Node* ptrNode = list.mFirst.get(); - while(ptrNode != nullptr) - { - stream << ptrNode->mData << ", "; - ptrNode = ptrNode->mNext.get(); - } - - return stream; - } + LinkedListIterator begin(); + LinkedListIterator end(); + + template + friend std::ostream& operator<<(std::ostream& stream, const LinkedList& list); private: + std::unique_ptr> mFirst; Node* mLast; int mSize {}; }; +template +class LinkedListIterator: public std::iterator +{ +public: + explicit LinkedListIterator(Node* ptrNode); + + LinkedListIterator& operator++(); + + bool operator !=(const LinkedListIterator& other); + + T& operator*(); + +private: + Node* mPtrNode; +}; + #include "linked_list.cc" diff --git a/course02/homework01/matt/test_linked_list.cc b/course02/homework01/matt/test_linked_list.cc index 96b7466..c8a90b4 100644 --- a/course02/homework01/matt/test_linked_list.cc +++ b/course02/homework01/matt/test_linked_list.cc @@ -1,5 +1,6 @@ #include #include "linked_list.h" +#include int main() { @@ -8,15 +9,23 @@ int main() l.Append(2); l.Append(3); - std::cout << "l:" << l << std::endl; + std::cout << "l: " << l << std::endl; LinkedList lCopyConstructed(l); - std::cout << "lCopyConstructed:" << lCopyConstructed << std::endl; + std::cout << "lCopyConstructed: " << lCopyConstructed << std::endl; LinkedList lAssigned; lAssigned = l; - std::cout << "lAssigned:" << lAssigned << std::endl; + std::cout << "lAssigned: " << lAssigned << std::endl; + + std::cout << "iterator: "; + for(auto i: l) + std::cout << i << ", "; + std::cout << std::endl; + + std::cout << "algorithm: "; + std::for_each(l.begin(), l.end(), [](int& i) { std::cout << i << ", " ; }); + std::cout << std::endl; return 0; } - diff --git a/course02/homework03/matt/test_throttle.cc b/course02/homework03/matt/test_throttle.cc new file mode 100644 index 0000000..d5255c6 --- /dev/null +++ b/course02/homework03/matt/test_throttle.cc @@ -0,0 +1,28 @@ +#include "throttle.cc" +#include +#include +#include + +int main() +{ + Throttle throttle; + + UserID id = 5; + + int i = 0; + for(; i<=20; i++) + { + std::ostringstream stringStream; + stringStream << "Hello " << i; + throttle.SendMessage(id, stringStream.str()); + } + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + + for(; i<=40; i++) + { + std::this_thread::sleep_for(std::chrono::milliseconds(800)); + std::ostringstream stringStream; + stringStream << "Hello " << i; + throttle.SendMessage(id, stringStream.str()); + } +} diff --git a/course02/homework03/matt/throttle.cc b/course02/homework03/matt/throttle.cc new file mode 100644 index 0000000..d3fab7a --- /dev/null +++ b/course02/homework03/matt/throttle.cc @@ -0,0 +1,50 @@ +#include "throttle.h" + +typedef std::chrono::milliseconds ms; +typedef std::chrono::duration fsec; + +template +double DurationToMillis(duration d) +{ + return std::chrono::duration_cast(d).count(); +} + +void Throttle::SendMessage(UserID id, std::string message) +{ + FlushMessages(id); + + TimestampedMessage tsm{message}; + auto& queue = mQueues[id]; + + Timestamp arrivalTime = Clock::now(); + + auto timeBetweenFirstLast = arrivalTime - queue.front().mArrivalTime; + auto timeToWait = mMessageInterval - timeBetweenFirstLast; + double millisToWait = DurationToMillis(timeToWait); + + if(queue.size() >= mMaxQueueSize) + { + printf("user %d message %s dropped, please wait %.0f millis \n", id, message.c_str(), millisToWait); + } + else + { + printf("user %d message %s accepted \n", id, message.c_str()); + queue.emplace_back(TimestampedMessage{message, arrivalTime}); + } +} + +void Throttle::FlushMessages(UserID id) +{ + auto& queue = mQueues[id]; + Timestamp now = Clock::now(); + while (!queue.empty()) + { + if (now - queue.front().mArrivalTime > mMessageInterval) + { + printf("user %d message %s popping \n", id, queue.front().mText.c_str()); + queue.pop_front(); + } + else + break; + } +} diff --git a/course02/homework03/matt/throttle.h b/course02/homework03/matt/throttle.h new file mode 100644 index 0000000..4d90678 --- /dev/null +++ b/course02/homework03/matt/throttle.h @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +typedef int UserID; +typedef std::chrono::high_resolution_clock Clock; +typedef std::chrono::time_point Timestamp; + + +struct TimestampedMessage +{ + TimestampedMessage(std::string message, Timestamp ts): + mText(message), mArrivalTime(ts) {}; + + TimestampedMessage(std::string message): + mText(message), mArrivalTime(Clock::now()) {}; + + std::string mText; + Timestamp mArrivalTime; +}; + +class Throttle +{ +public: + void SendMessage(UserID id, std::string message); + +private: + void FlushMessages(UserID id); + + const int mMaxQueueSize = 10; + const std::chrono::milliseconds mMessageInterval{10000}; + std::unordered_map> mQueues; +};