summaryrefslogtreecommitdiff
path: root/cpp/lib/broker/Reference.h
blob: e453645a5485cd72f078619572b797e61d703a75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#ifndef _broker_Reference_h
#define _broker_Reference_h

/*
 *
 * Copyright (c) 2006 The Apache Software Foundation
 *
 * Licensed 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 <string>
#include <vector>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/range.hpp>

namespace qpid {

namespace framing {
class MessageAppendBody;
}

namespace broker {

class MessageMessage;
class ReferenceRegistry;

/**
 * A reference is an accumulation point for data in a multi-frame
 * message. A reference can be used by multiple transfer commands to
 * create multiple messages, so the reference tracks which commands
 * are using it. When the reference is closed, all the associated
 * transfers are completed.
 *
 * THREAD UNSAFE: per-channel resource, access to channels is
 * serialized.
 */
class Reference
{
  public:
    typedef std::string Id;
    typedef boost::shared_ptr<Reference> shared_ptr;
    typedef boost::shared_ptr<MessageMessage> MessagePtr;
    typedef std::vector<MessagePtr> Messages;
    typedef boost::shared_ptr<framing::MessageAppendBody> AppendPtr;
    typedef std::vector<AppendPtr> Appends;

    Reference(const Id& id_=Id(), ReferenceRegistry* reg=0)
        : id(id_), size(0), registry(reg) {}
    
    const std::string& getId() const { return id; }
    uint64_t getSize() const { return size; }

    /** Add a message to be completed with this reference */
    void addMessage(MessagePtr message) { messages.push_back(message); }

    /** Append more data to the reference */
    void append(AppendPtr ptr);

    /** Close the reference, complete each associated message */
    void close();

    const Appends& getAppends() const { return appends; }
    const Messages& getMessages() const { return messages; }
    
  private:
    Id id;
    uint64_t size;
    ReferenceRegistry* registry;
    Messages messages;
    Appends appends;
};


/**
 * A registry/factory for references.
 * 
 * THREAD UNSAFE: per-channel resource, access to channels is
 * serialized.
 */
class ReferenceRegistry {
  public:
    ReferenceRegistry() {};
    Reference::shared_ptr open(const Reference::Id& id);
    Reference::shared_ptr get(const Reference::Id& id);

  private:
    typedef std::map<Reference::Id, Reference::shared_ptr> ReferenceMap;
    ReferenceMap references;

    // Reference calls references.erase().
    friend class Reference;
};


}} // namespace qpid::broker



#endif  /*!_broker_Reference_h*/