LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
Chunk.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 
33 #ifndef LSST_AP_CHUNK_H
34 #define LSST_AP_CHUNK_H
35 
36 #include <cassert>
37 #include <stdexcept>
38 #include <algorithm>
39 
40 #include "boost/noncopyable.hpp"
41 #include "boost/static_assert.hpp"
42 // #include "boost/type_traits/has_trivial_assign.hpp"
43 // #include "boost/type_traits/has_trivial_copy.hpp"
44 // #include "boost/type_traits/has_trivial_destructor.hpp"
45 
46 #include "Common.h"
47 #include "DataTraits.h"
48 #include "Fifo.h"
49 
50 
51 namespace lsst {
52 namespace ap {
53 
54 
57 
58  static boost::uint32_t const MAGIC = 0xdecade14;
59 
60  boost::uint32_t _magic;
64 
66  _magic(MAGIC),
67  _numRecords(0),
68  _numDeletes(0),
69  _recordSize(0)
70  {}
71 
72  bool isValid() const {
73  return _magic == MAGIC;
74  }
75 };
76 
77 
84 template <int MaxBlocksPerChunk>
85 class ChunkDescriptor : private boost::noncopyable {
86 public :
87 
88  int _chunkId;
89  int _visitId;
90  int _nextChunk;
91 
96  bool _usable;
97 
98  int _numBlocks;
99  int _nextBlock;
100  int _index;
101  int _size;
102  int _delta;
103  std::size_t _curBlockOffset;
104 
108  std::size_t _blocks[MaxBlocksPerChunk];
109 
110 
112 
113  void initialize();
114 
115  void clear() {
116  _nextBlock = 0;
117  _index = 0;
118  _size = 0;
119  _delta = 0;
120  _curBlockOffset = 0;
121  }
122 
123  bool operator<(ChunkDescriptor const & cd) const {
124  return _visitId < cd._visitId || (_visitId == cd._visitId && _chunkId < cd._chunkId);
125  }
126 
127  // detail::HashedSet requirements
128  int getId() const { return _chunkId; }
129  int getNextInChain() const { return _nextChunk; }
130  void setId(int const id) { _chunkId = id; }
131  void setNextInChain(int const id) { _nextChunk = id; }
132 };
133 
134 
142 typedef unsigned char ChunkEntryFlag;
143 
144 
245 template <typename AllocatorT, typename DataT, typename TraitsT = DataTraits<DataT> >
246 class ChunkRef {
247 
248 // BOOST_STATIC_ASSERT(boost::has_trivial_assign<DataT>::value);
249 // BOOST_STATIC_ASSERT(boost::has_trivial_copy<DataT>::value);
250 // BOOST_STATIC_ASSERT(boost::has_trivial_destructor<DataT>::value);
251 
252 public :
253 
254  typedef DataT Entry;
255 
256  enum EntryFlag {
257  IN_DELTA = 0x01,
258  UNCOMMITTED = 0x02,
259  INSERTED = 0x04,
260  DELETED = 0x08
261  };
262 
263  static int const ENTRIES_PER_BLOCK_LOG2 = TraitsT::ENTRIES_PER_BLOCK_LOG2;
264  static int const MAX_BLOCKS = TraitsT::MAX_BLOCKS_PER_CHUNK;
265  static std::size_t const BLOCK_SIZE =
266  (sizeof(DataT) + sizeof(ChunkEntryFlag)) << ENTRIES_PER_BLOCK_LOG2;
267 
268  typedef ChunkDescriptor<MAX_BLOCKS> Descriptor;
269 
270  ChunkRef(Descriptor * desc, AllocatorT * all) : _descriptor(desc), _allocator(all) {}
271 
272  ~ChunkRef() {
273  _descriptor = 0;
274  _allocator = 0;
275  }
276 
277  boost::int64_t getId() const {
278  return _descriptor->_chunkId;
279  }
280  int getVisitId() const {
281  return _descriptor->_visitId;
282  }
283  bool isUsable() const {
284  return _descriptor->_usable;
285  }
286  void setUsable() {
287  _descriptor->_usable = true;
288  }
289 
291  DataT const & get(int const i) const {
292  assert(i >= 0 && i < _descriptor->_size);
293  return *reinterpret_cast<DataT const *>(map(
294  _descriptor->_blocks[i >> ENTRIES_PER_BLOCK_LOG2] +
295  sizeof(ChunkEntryFlag)*(1 << ENTRIES_PER_BLOCK_LOG2) +
296  (i & ((1 << ENTRIES_PER_BLOCK_LOG2) - 1))*sizeof(DataT)
297  ));
298  }
299 
301  DataT const * getBlock(int const b) const {
302  assert(b >= 0 && b < _descriptor->_numBlocks);
303  return reinterpret_cast<DataT const *>(map(
304  _descriptor->_blocks[b] + (sizeof(ChunkEntryFlag) << ENTRIES_PER_BLOCK_LOG2)
305  ));
306  }
307 
309  DataT * getBlock(int const b) {
310  assert(b >= 0 && b < _descriptor->_numBlocks);
311  return reinterpret_cast<DataT *>(map(
312  _descriptor->_blocks[b] + (sizeof(ChunkEntryFlag) << ENTRIES_PER_BLOCK_LOG2)
313  ));
314  }
315 
317  ChunkEntryFlag getFlag(int const i) const {
318  assert(i >= 0 && i < _descriptor->_size);
319  return *reinterpret_cast<ChunkEntryFlag const *>(map(
320  _descriptor->_blocks[i >> ENTRIES_PER_BLOCK_LOG2] +
321  (i & ((1u << ENTRIES_PER_BLOCK_LOG2) - 1))*sizeof(ChunkEntryFlag)
322  ));
323  }
324 
326  ChunkEntryFlag const * getFlagBlock(int const b) const {
327  assert(b >= 0 && b < _descriptor->_numBlocks);
328  return reinterpret_cast<ChunkEntryFlag const *>(map(_descriptor->_blocks[b]));
329  }
330 
332  ChunkEntryFlag * getFlagBlock(int const b) {
333  assert(b >= 0 && b < _descriptor->_numBlocks);
334  return reinterpret_cast<ChunkEntryFlag *>(map(_descriptor->_blocks[b]));
335  }
336 
338  void insert(DataT const & data) {
339  insert(data, IN_DELTA | UNCOMMITTED | INSERTED);
340  }
341 
343  void remove(int const i) {
344  assert(i >= 0 && i < _descriptor->_size);
345  ChunkEntryFlag * f = reinterpret_cast<ChunkEntryFlag *>(map(
346  _descriptor->_blocks[i >> ENTRIES_PER_BLOCK_LOG2] +
347  (i & ((1 << ENTRIES_PER_BLOCK_LOG2) - 1))*sizeof(ChunkEntryFlag)
348  ));
349  if ((*f & DELETED) == 0) { // removing an entry that is already deleted is a no-op
350  *f |= DELETED | UNCOMMITTED;
351  }
352  }
353 
355  int size() const {
356  return _descriptor->_size;
357  }
358 
360  int delta() const {
361  return _descriptor->_delta;
362  }
363 
365  int capacity() const {
366  return _descriptor->_numBlocks << ENTRIES_PER_BLOCK_LOG2;
367  }
368 
370  int blocks() const {
371  return _descriptor->_nextBlock;
372  }
373 
375  int entries(int const b) const {
376  assert(b >= 0 && b < _descriptor->_nextBlock);
377  return (b < _descriptor->_nextBlock - 1) ? (1 << ENTRIES_PER_BLOCK_LOG2) : _descriptor->_index;
378  }
379 
381  void clear() {
382  _descriptor->clear();
383  }
384 
385  void reserve(int const n);
386  bool pack(int const i = 0);
387  bool rollback();
388  void commit(bool clearDelta = false);
389 
390  void read(std::string const & name, bool const compressed);
391  void readDelta(std::string const & name, bool const compressed);
392 
393  void write(
394  std::string const & name,
395  bool const overwrite,
396  bool const compressed,
397  bool const withDelta = true
398  ) const;
399  void writeDelta(
400  std::string const & name,
401  bool const overwrite,
402  bool const compressed
403  ) const;
404 
405 private :
406 
407  // Ensure number of entries per-block is a power of 2 greater than 512.
408  // This avoids alignment issues for chunk entries and guarantees that
409  // flags and chunk entries live on different cachelines.
410  BOOST_STATIC_ASSERT(TraitsT::ENTRIES_PER_BLOCK_LOG2 >= 9);
411 
412  Descriptor * _descriptor;
413  AllocatorT * _allocator;
414 
416  unsigned char * map(std::size_t const off) {
417  return reinterpret_cast<unsigned char *>(_allocator) + off;
418  }
419 
421  unsigned char const * map(std::size_t const off) const {
422  return reinterpret_cast<unsigned char const *>(_allocator) + off;
423  }
424 
425  void applyDeletes(
426  int const * const deletes,
427  int const numDeletes,
428  int const end
429  );
430 
431  void insert(DataT const & data, ChunkEntryFlag const flags);
432 
433  void setFlags(
434  int const b,
435  ChunkEntryFlag const flags,
436  int const i = 0,
437  int const n = (1 << ENTRIES_PER_BLOCK_LOG2)
438  );
439 };
440 
441 
442 }} // end of namespace lsst::ap
443 
444 #endif // LSST_AP_CHUNK_H
445 
table::Key< table::Array< double > > cd
Definition: Wcs.cc:1043
bool operator<(ChunkDescriptor const &cd) const
Definition: Chunk.h:123
bool isValid() const
Definition: Chunk.h:72
unsigned char ChunkEntryFlag
Definition: Chunk.h:142
int getId() const
Definition: Chunk.h:128
int _chunkId
Identifier for the chunk.
Definition: Chunk.h:88
A fixed capacity FIFO buffer for integers.
int _numBlocks
Number of memory blocks allocated.
Definition: Chunk.h:98
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, bool >::type all(Scalar const &scalar)
Definition: operators.h:1186
int getNextInChain() const
Definition: Chunk.h:129
static boost::uint32_t const MAGIC
Definition: Chunk.h:58
std::size_t _curBlockOffset
Offset of the current block.
Definition: Chunk.h:103
int _nextChunk
Index of the next chunk in the same hash bucket as this one.
Definition: Chunk.h:90
void setNextInChain(int const id)
Definition: Chunk.h:131
Fifo< MAX_VISITS_IN_FLIGHT > _interestedParties
FIFO of visits to a FOV that overlaps the chunk.
Definition: Chunk.h:106
std::size_t _blocks[MaxBlocksPerChunk]
List of memory block offsets for allocated blocks.
Definition: Chunk.h:108
Simple header for binary chunk files – allows some sanity checking at read time.
Definition: Chunk.h:56
Master header file for the association pipeline.
A generic descriptor containing state for different kinds of chunks.
Definition: Chunk.h:85
int _delta
Index of first entry marked IN_DELTA.
Definition: Chunk.h:102
Compile time constants related to data types to be stored in chunks.
int _index
Index of the next free entry in the current block.
Definition: Chunk.h:100
int id
Definition: CR.cc:151
void setId(int const id)
Definition: Chunk.h:130
afw::table::Key< double > b
int _size
Total number of entries.
Definition: Chunk.h:101
int _nextBlock
Index of the next block to insert into.
Definition: Chunk.h:99
int _visitId
Identifier for the visit that currently owns the chunk.
Definition: Chunk.h:89
boost::uint32_t _magic
Definition: Chunk.h:60