1 /***************************************************************************
2  *  foxxll/mng/bid.hpp
3  *
4  *  Part of FOXXLL. See http://foxxll.org
5  *
6  *  Copyright (C) 2002-2004 Roman Dementiev <dementiev@mpi-sb.mpg.de>
7  *  Copyright (C) 2009, 2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
8  *  Copyright (C) 2009 Johannes Singler <singler@ira.uka.de>
9  *  Copyright (C) 2013 Timo Bingmann <tb@panthema.net>
10  *  Copyright (C) 2018 Manuel Penschuck <foxxll@manuel.jetzt>
11  *
12  *  Distributed under the Boost Software License, Version 1.0.
13  *  (See accompanying file LICENSE_1_0.txt or copy at
14  *  http://www.boost.org/LICENSE_1_0.txt)
15  **************************************************************************/
16 
17 #ifndef FOXXLL_MNG_BID_HEADER
18 #define FOXXLL_MNG_BID_HEADER
19 
20 #include <cstring>
21 #include <iomanip>
22 #include <ostream>
23 #include <sstream>
24 
25 #include <foxxll/common/utils.hpp>
26 #include <foxxll/io/file.hpp>
27 #include <foxxll/io/request.hpp>
28 #include <tlx/simple_vector.hpp>
29 
30 namespace foxxll {
31 
32 //! \addtogroup foxxll_mnglayer
33 //! \{
34 
35 //! Block identifier class.
36 //!
37 //! Stores block identity, given by file and offset within the file
38 template <size_t Size>
39 class BID
40 {
41 public:
42     //! Block size
43     static constexpr size_t size = Size;
44     //! Blocks size, given by the parameter
45     static constexpr size_t t_size = Size;
46 
47     //! pointer to the file of the block
48     file* storage = nullptr;
49     //! offset within the file of the block (uint64_t)
50     external_size_type offset = 0;
51 
52     BID() = default;
53 
BID(file * s,const external_size_type & o)54     BID(file* s, const external_size_type& o) : storage(s), offset(o) { }
55 
56     //! construction from another block size
57     template <size_t BlockSize>
BID(const BID<BlockSize> & obj)58     explicit BID(const BID<BlockSize>& obj)
59         : storage(obj.storage), offset(obj.offset) { }
60 
61     //! assignment from another block size
62     template <size_t BlockSize>
operator =(const BID<BlockSize> & obj)63     BID& operator = (const BID<BlockSize>& obj)
64     {
65         storage = obj.storage;
66         offset = obj.offset;
67         return *this;
68     }
69 
valid() const70     bool valid() const
71     {
72         return storage != nullptr;
73     }
74 
is_managed() const75     bool is_managed() const
76     {
77         return storage->get_allocator_id() != file::NO_ALLOCATOR;
78     }
79 
80     //! Writes data to the disk(s).
write(void * data,size_t data_size,completion_handler on_complete=completion_handler ())81     request_ptr write(void* data, size_t data_size,
82                       completion_handler on_complete = completion_handler())
83     {
84         return storage->awrite(data, offset, data_size, on_complete);
85     }
86 
87     //! Reads data from the disk(s).
read(void * data,size_t data_size,completion_handler on_complete=completion_handler ())88     request_ptr read(void* data, size_t data_size,
89                      completion_handler on_complete = completion_handler())
90     {
91         return storage->aread(data, offset, data_size, on_complete);
92     }
93 
operator ==(const BID<Size> & b) const94     bool operator == (const BID<Size>& b) const
95     {
96         return storage == b.storage && offset == b.offset;
97     }
98 
operator !=(const BID<Size> & b) const99     bool operator != (const BID<Size>& b) const
100     {
101         return !operator == (b);
102     }
103 };
104 
105 /*!
106  * Specialization of block identifier class (BID) for variable size block size.
107  *
108  * Stores block identity, given by file, offset within the file, and size of the
109  * block
110  */
111 template <>
112 class BID<0>
113 {
114 public:
115     //! pointer to the file of the block
116     file* storage = nullptr;
117     //! offset within the file of the block (uint64_t)
118     external_size_type offset = 0;
119     //! size of the block in bytes
120     size_t size = 0;
121 
122     //! Blocks size, given by the parameter
123     static constexpr size_t t_size = 0;
124 
125     BID() = default;
126 
BID(file * f,const external_size_type & o,size_t s)127     BID(file* f, const external_size_type& o, size_t s)
128         : storage(f), offset(o), size(s) { }
129 
valid() const130     bool valid() const
131     {
132         return (storage != nullptr);
133     }
134 
is_managed() const135     bool is_managed() const
136     {
137         return storage->get_allocator_id() != file::NO_ALLOCATOR;
138     }
139 
140     //! Writes data to the disk(s).
write(void * data,size_t data_size,completion_handler on_complete=completion_handler ())141     request_ptr write(void* data, size_t data_size,
142                       completion_handler on_complete = completion_handler())
143     {
144         return storage->awrite(data, offset, data_size, on_complete);
145     }
146 
147     //! Reads data from the disk(s).
read(void * data,size_t data_size,completion_handler on_complete=completion_handler ())148     request_ptr read(void* data, size_t data_size,
149                      completion_handler on_complete = completion_handler())
150     {
151         return storage->aread(data, offset, data_size, on_complete);
152     }
153 
operator ==(const BID<0> & b) const154     bool operator == (const BID<0>& b) const
155     {
156         return storage == b.storage && offset == b.offset && size == b.size;
157     }
158 
operator !=(const BID<0> & b) const159     bool operator != (const BID<0>& b) const
160     {
161         return !operator == (b);
162     }
163 };
164 
165 /**
166  * Prints a BID to an ostream using the following format
167  * \verbatim
168  *  [0x12345678|0]0x00100000/0x00010000
169  *  [file ptr|file id]offset/size
170  * \endverbatim
171  *
172  * \note
173  * Can be used to replace the obsolete FMT_BID macro
174  */
175 template <size_t BlockSize>
operator <<(std::ostream & s,const BID<BlockSize> & bid)176 std::ostream& operator << (std::ostream& s, const BID<BlockSize>& bid)
177 {
178     std::stringstream ss;
179 
180     ss << "[" << static_cast<void*>(bid.storage) << "|";
181 
182     if (bid.storage) {
183         ss << bid.storage->get_allocator_id();
184     }
185     else {
186         ss << "?";
187     }
188 
189     ss << "]0x" << std::hex << std::setfill('0') << std::setw(8) << bid.offset
190        << "/0x" << std::setw(8) << bid.size << std::dec;
191 
192     s << ss.str();
193 
194     return s;
195 }
196 
197 template <size_t BlockSize>
198 using BIDArray = tlx::simple_vector<BID<BlockSize> >;
199 
200 //! \}
201 
202 } // namespace foxxll
203 
204 #endif // !FOXXLL_MNG_BID_HEADER
205 
206 /**************************************************************************/
207