blob: 93013a5e2c3ded8c4cfd0af219c9863a2e635226 [file] [log] [blame]
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
19 * 卞超轶 Chaoyi Bian <bcy@pku.edu.cn>
20 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
21 */
22
23#ifndef SYNC_SEQ_NO_H
24#define SYNC_SEQ_NO_H
25
Alexander Afanasyevb5547e32012-03-01 21:59:38 -080026#include <boost/cstdint.hpp>
Alexander Afanasyeve00ffbe2012-03-05 00:01:36 -080027#include "sync-digest.h"
Alexander Afanasyevb5547e32012-03-01 21:59:38 -080028
Alexander Afanasyev017784c2012-03-02 11:44:13 -080029namespace Sync {
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080030
31/**
Alexander Afanasyev1fbdcdd2012-03-05 23:14:33 -080032 * @ingroup sync
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080033 * @brief Sequence number abstraction
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080034 */
Alexander Afanasyeve00ffbe2012-03-05 00:01:36 -080035class SeqNo
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080036{
37public:
38 /**
Alexander Afanasyev1fbdcdd2012-03-05 23:14:33 -080039 * @brief Copy constructor
40 * @param seq sequence number object to copy from
41 */
42 SeqNo (const SeqNo &seq)
43 {
44 *this = seq;
45 }
46
47 /**
48 * @brief Assignment operator
49 * @param seq sequence number object to copy from
50 */
51 SeqNo &
52 operator = (const SeqNo &seq)
53 {
54 m_session = seq.m_session;
55 m_seq = seq.m_seq;
56
57 return *this;
58 }
59
60 /**
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080061 * @brief Constructor with just sequence number. Session assumed to be zero
62 * @param seq Sequence number
63 */
64 SeqNo (uint32_t seq)
65 : m_session (0)
66 , m_seq (seq)
67 { }
68
69 /**
70 * @brief Constructor with session and sequence id
71 * @param session Session ID
72 * @param seq Sequence number
73 */
74 SeqNo (uint32_t session, uint32_t seq)
75 : m_session (session)
76 , m_seq (seq)
77 { }
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080078
Alexander Afanasyev1fbdcdd2012-03-05 23:14:33 -080079 /**
80 * @brief Get sequence number digest
81 *
82 * Digest will be calculated every time it is requested
83 */
84 DigestConstPtr
Alexander Afanasyeve00ffbe2012-03-05 00:01:36 -080085 getDigest () const;
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -080086
87 /**
88 * @brief Compare if one sequence number is lower
89 * @param seq Another sequence number to compare with
90 *
91 * tuple (session1, seq1) is less than (session2, seq2) in two cases:
92 * 1. session1 < session2
93 * 2. session1 == session2 and seq1 < seq2
94 */
95 bool
96 operator < (const SeqNo &seq) const
97 {
98 return m_session < seq.m_session || (m_session == seq.m_session && m_seq < seq.m_seq);
99 }
100
101 /**
102 * @brief Compare if two sequence numbers are equal
103 * @param seq Another sequence number to compare with
104 */
105 bool
106 operator == (const SeqNo &seq) const
107 {
108 return m_session == seq.m_session && m_seq == seq.m_seq;
109 }
Alexander Afanasyeve00ffbe2012-03-05 00:01:36 -0800110
Alexander Afanasyev1fbdcdd2012-03-05 23:14:33 -0800111 /**
112 * @brief Get session id
113 */
114 uint32_t getSession () const
115 { return m_session; }
Alexander Afanasyeve00ffbe2012-03-05 00:01:36 -0800116
Alexander Afanasyev1fbdcdd2012-03-05 23:14:33 -0800117 /**
118 * @brief Get sequence number
119 */
120 uint32_t getSeq () const
121 { return m_seq; }
Alexander Afanasyeve00ffbe2012-03-05 00:01:36 -0800122
123private:
124 /**
125 * @brief Session ID (e.g., after crash, application will choose new session ID.
126 *
127 * Note that session IDs for the same name should always increase. So, the good choice
128 * for the session ID is client's timestamp
129 */
130 uint32_t m_session;
131
132 /**
133 * @brief Sequence number
134 *
135 * Sequence number for a session always starts with 0 and goes to max value.
136 *
137 * For now, wrapping sequence number after max to zero is not supported
138 */
139 uint32_t m_seq;
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -0800140};
141
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -0800142inline std::ostream &
143operator << (std::ostream &os, const SeqNo &seqno)
144{
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800145 os << "<session>" << seqno.getSession () << "</session><seqno>" << seqno.getSeq () << "</seqno>";
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -0800146 return os;
147}
148
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -0800149} // Sync
150
Alexander Afanasyev7a696fb2012-03-01 17:17:22 -0800151#endif // SYNC_SEQ_NO_H