summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/broker/Credit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/qpid/broker/Credit.cpp')
-rw-r--r--cpp/src/qpid/broker/Credit.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/cpp/src/qpid/broker/Credit.cpp b/cpp/src/qpid/broker/Credit.cpp
new file mode 100644
index 0000000000..c0e0b3b3d3
--- /dev/null
+++ b/cpp/src/qpid/broker/Credit.cpp
@@ -0,0 +1,151 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+#include "qpid/broker/Credit.h"
+
+namespace qpid {
+namespace broker {
+
+const uint32_t CreditBalance::INFINITE_CREDIT(0xFFFFFFFF);
+CreditBalance::CreditBalance() : balance(0) {}
+CreditBalance::~CreditBalance() {}
+void CreditBalance::clear() { balance = 0; }
+void CreditBalance::grant(uint32_t value)
+{
+ if (balance != INFINITE_CREDIT) {
+ if (value == INFINITE_CREDIT) {
+ balance = INFINITE_CREDIT;
+ } else if (INFINITE_CREDIT - balance > value) {
+ balance += value;
+ } else {
+ balance = INFINITE_CREDIT - 1;
+ }
+ }
+}
+void CreditBalance::consume(uint32_t value) { if (!unlimited()) balance -= value; }
+bool CreditBalance::check(uint32_t required) const { return balance >= required; }
+uint32_t CreditBalance::remaining() const { return balance; }
+uint32_t CreditBalance::allocated() const { return balance; }
+bool CreditBalance::unlimited() const { return balance == INFINITE_CREDIT; }
+
+CreditWindow::CreditWindow() : used(0) {}
+bool CreditWindow::check(uint32_t required) const { return CreditBalance::check(used + required); }
+void CreditWindow::consume(uint32_t value) { if (!unlimited()) used += value; }
+void CreditWindow::move(uint32_t value) { if (!unlimited()) used -= value; }
+uint32_t CreditWindow::remaining() const { return allocated() - used; }
+uint32_t CreditWindow::consumed() const { return used; }
+
+Credit::Credit() : windowing(true) {}
+void Credit::setWindowMode(bool b) { windowing = b; }
+bool Credit::isWindowMode() const { return windowing; }
+void Credit::addByteCredit(uint32_t value)
+{
+ bytes().grant(value);
+}
+void Credit::addMessageCredit(uint32_t value)
+{
+ messages().grant(value);
+}
+void Credit::cancel()
+{
+ messages().clear();
+ bytes().clear();
+}
+void Credit::moveWindow(uint32_t m, uint32_t b)
+{
+ if (windowing) {
+ window.messages.move(m);
+ window.bytes.move(b);
+ }
+}
+void Credit::consume(uint32_t m, uint32_t b)
+{
+ messages().consume(m);
+ bytes().consume(b);
+}
+bool Credit::check(uint32_t m, uint32_t b) const
+{
+ return messages().check(m) && bytes().check(b);
+}
+CreditPair<uint32_t> Credit::used() const
+{
+ CreditPair<uint32_t> result;
+ if (windowing) {
+ result.messages = window.messages.consumed();
+ result.bytes = window.bytes.consumed();
+ } else {
+ result.messages = 0;
+ result.bytes = 0;
+ }
+ return result;
+}
+CreditPair<uint32_t> Credit::allocated() const
+{
+ CreditPair<uint32_t> result;
+ result.messages = messages().allocated();
+ result.bytes = bytes().allocated();
+ return result;
+}
+Credit::operator bool() const
+{
+ return check(1,1);
+}
+CreditBalance& Credit::messages()
+{
+ if (windowing) return window.messages;
+ else return balance.messages;
+}
+CreditBalance& Credit::bytes()
+{
+ if (windowing) return window.bytes;
+ else return balance.bytes;
+}
+const CreditBalance& Credit::messages() const
+{
+ if (windowing) return window.messages;
+ else return balance.messages;
+}
+const CreditBalance& Credit::bytes() const
+{
+ if (windowing) return window.bytes;
+ else return balance.bytes;
+}
+std::ostream& operator<<(std::ostream& out, const CreditBalance& b)
+{
+ if (b.unlimited()) return out << "unlimited";
+ else return out << b.balance;
+}
+std::ostream& operator<<(std::ostream& out, const CreditWindow& w)
+{
+ if (w.unlimited()) return out << ((CreditBalance) w);
+ else return out << w.remaining() << " (from window of " << w.allocated() << ")";
+}
+template <class T>
+std::ostream& operator<<(std::ostream& out, const CreditPair<T>& pair)
+{
+ return out << "messages: " << pair.messages << " bytes: " << pair.bytes;
+}
+std::ostream& operator<<(std::ostream& out, const Credit& c)
+{
+ if (c.windowing) return out << c.window;
+ else return out << c.balance;
+}
+
+}} // namespace qpid::broker