1 #ifndef LIBGEODECOMP_STORAGE_PATCHBUFFER_H
2 #define LIBGEODECOMP_STORAGE_PATCHBUFFER_H
3 
4 #include <deque>
5 #include <libgeodecomp/storage/patchaccepter.h>
6 #include <libgeodecomp/storage/patchprovider.h>
7 
8 namespace LibGeoDecomp {
9 
10 template<class GRID_TYPE1, class GRID_TYPE2>
11 class PatchBuffer :
12         public PatchAccepter<GRID_TYPE1>,
13         public PatchProvider<GRID_TYPE2>
14 {
15 public:
16     friend class PatchBufferTest;
17     typedef typename GRID_TYPE1::CellType CellType;
18     typedef typename SerializationBuffer<CellType>::BufferType BufferType;
19     const static int DIM = GRID_TYPE1::DIM;
20 
21     using PatchAccepter<GRID_TYPE1>::checkNanoStepPut;
22     using PatchAccepter<GRID_TYPE1>::requestedNanoSteps;
23     using PatchProvider<GRID_TYPE2>::checkNanoStepGet;
24     using PatchProvider<GRID_TYPE2>::storedNanoSteps;
25 
26     explicit PatchBuffer(const Region<DIM>& region = Region<DIM>()) :
region(region)27         region(region)
28     {}
29 
put(const GRID_TYPE1 & grid,const Region<DIM> &,const std::size_t nanoStep)30     virtual void put(
31         const GRID_TYPE1& grid,
32         const Region<DIM>& /*validRegion*/,
33         const std::size_t nanoStep)
34     {
35         // It would be nice to check if validRegion was actually a
36         // superset of the region we'll save, but that would be
37         // prohibitively slow.
38         if (!checkNanoStepPut(nanoStep)) {
39             return;
40         }
41 
42         storedRegions.push_back(BufferType());
43         BufferType& buffer = storedRegions.back();
44         buffer = SerializationBuffer<CellType>::create(region);
45 
46         GridVecConv::gridToVector(grid, &buffer, region);
47         storedNanoSteps << (min)(requestedNanoSteps);
48         erase_min(requestedNanoSteps);
49     }
50 
51     virtual void get(
52         GRID_TYPE2 *destinationGrid,
53         const Region<DIM>& patchableRegion,
54         const std::size_t nanoStep,
55         const bool remove=true)
56     {
57         checkNanoStepGet(nanoStep);
58         if (storedRegions.empty()) {
59             throw std::logic_error("no region available");
60         }
61 
62         GridVecConv::vectorToGrid(
63             storedRegions.front(), destinationGrid, region);
64 
65         if (remove) {
66             storedRegions.pop_front();
67             erase_min(storedNanoSteps);
68         }
69 
70     }
71 
72 private:
73     Region<DIM> region;
74     std::deque<BufferType> storedRegions;
75 };
76 
77 }
78 
79 #endif
80