
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2008-03-12 Matthieu Garrigues <garrigues@lrde.epita.fr> Add to sanbox an image type maped on the hard disk. * milena/sandbox/garrigues/tiled_image2d: New. * milena/sandbox/garrigues/tiled_image2d/tiled_image2d.cc: New. * milena/sandbox/garrigues/tiled_image2d/tiled_image2d.hh: New. * milena/sandbox/garrigues/tiled_image2d/backend/file.hh: New. * milena/sandbox/garrigues/tiled_image2d/backend/ios.hh: New. * milena/sandbox/garrigues/tiled_image2d/backend/mmap.hh: New. * milena/sandbox/garrigues/tiled_image2d/backend: New. * milena/sandbox/garrigues/tiled_image2d/block.hh: New. * milena/sandbox/garrigues/tiled_image2d/context.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/all.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/image2d/all.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/image2d/lrtb.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/image2d/tblr.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/image2d: New. * milena/sandbox/garrigues/tiled_image2d/layout/layout2d.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/page2d/all.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/page2d/lrtb.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/page2d/tblr.hh: New. * milena/sandbox/garrigues/tiled_image2d/layout/page2d: New. * milena/sandbox/garrigues/tiled_image2d/layout: New. * milena/sandbox/garrigues/tiled_image2d/page.hh: New. * milena/sandbox/garrigues/tiled_image2d/paged_image.hh: New. * milena/sandbox/garrigues/tiled_image2d/support/lru.hh: New. * milena/sandbox/garrigues/tiled_image2d/support/simple.hh: New. * milena/sandbox/garrigues/tiled_image2d/support: New. --- backend/file.hh | 76 ++++++++++ backend/ios.hh | 79 ++++++++++ backend/mmap.hh | 125 +++++++++++++++++ block.hh | 63 ++++++++ context.hh | 38 +++++ layout/all.hh | 8 + layout/image2d/all.hh | 7 layout/image2d/lrtb.hh | 65 ++++++++ layout/image2d/tblr.hh | 33 ++++ layout/layout2d.hh | 56 +++++++ layout/page2d/all.hh | 7 layout/page2d/lrtb.hh | 52 +++++++ layout/page2d/tblr.hh | 21 ++ page.hh | 91 ++++++++++++ paged_image.hh | 56 +++++++ support/lru.hh | 198 +++++++++++++++++++++++++++ support/simple.hh | 35 ++++ tiled_image2d.cc | 45 ++++++ tiled_image2d.hh | 357 +++++++++++++++++++++++++++++++++++++++++++++++++ 19 files changed, 1412 insertions(+) Index: trunk/milena/sandbox/garrigues/tiled_image2d/paged_image.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/paged_image.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/paged_image.hh (revision 1778) @@ -0,0 +1,56 @@ +#ifndef paged_image_hh +#define paged_image_hh + +#include "page.hh" + +template<typename T, typename Domain, typename Layout, typename Support> +struct paged_image { + typedef Domain domain_type; + typedef Support support_type; + typedef Layout layout_type; + + typedef page<T, typename Layout::page_layout> page_type; + + paged_image(const Domain& d, Support& s) + : domain_(d), support_(s) + {} + + + const domain_type& domain() const { return domain_; } + + template<typename Point> + page_type page_at(const Point& p) { + unsigned page_n = Layout::image_layout::page_at(*this, p); + return page_type(support_.get_block(page_n)); + } + + template<typename Point> + void prepare(const Point& p) { + unsigned page_n = Layout::image_layout::page_at(*this, p); + support_.prepare(page_n); + } + + template<typename Point> + T& operator()(const Point& p) { + unsigned page_n = Layout::image_layout::page_at(*this, p); + // note: although the page instance goes + // out of scope, the reference stays valid + // because the block is ultimately held by support. + return page_type(support_.get_block(page_n))(Layout::image_layout::changeref(p)); + } + + template<typename Point> + const T& operator()(const Point& p) const { + unsigned page_n = Layout::page_at(*this, p); + // note: although the page instance goes + // out of scope, the reference stays valid + // because the block is ultimately held by support. + return page_type(const_cast<support_type&>(support_).get_block(page_n))(Layout::image_layout::changeref(p)); + } + + + domain_type domain_; + support_type& support_; +}; + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/context.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/context.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/context.hh (revision 1778) @@ -0,0 +1,38 @@ +#ifndef context_hh +#define context_hh + +#include "ersatz/domain.hh" +#include "page.hh" +#include "paged_image.hh" + +template<typename T, typename Layout, + template<typename Block> class Backend, + template<typename Backend> class Support, + typename Domain = domain<Layout::dim, unsigned> > +struct context { + + typedef typename Layout::template block_<T> block_type; + + typedef T value_type; + + enum { dim = Layout::dim }; + + typedef Backend<block_type> backend_type; + + typedef Support<backend_type> support_type; + + typedef Layout layout_type; + typedef typename layout_type::page_layout page_layout; + typedef typename layout_type::image_layout image_layout; + + typedef page<T, page_layout> page_type; + + typedef Domain domain_type; + + typedef paged_image<value_type, domain_type, layout_type, support_type> image_type; + +}; + + + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/backend/ios.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/backend/ios.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/backend/ios.hh (revision 1778) @@ -0,0 +1,79 @@ +#ifndef ios_backend_hh +#define ios_backend_hh + +#include <iostream> +#include <cassert> + +template<typename Block> +struct ios_backend { + typedef Block block_type; + + ios_backend(std::iostream& ios, unsigned n_blocks) + : ios_(ios), size_(n_blocks) { + assert(ios_.good()); + loaded_ = new Block*[n_blocks]; + for (Block **p = loaded_; p < loaded_ + n_blocks; ++p) + *p = 0; + } + + ~ios_backend() { + for (unsigned n = 0; n < size_; ++n) + if (loaded_[n]) { + commit(n); + delete loaded_[n]; + } + delete[] loaded_; + } + + unsigned size() { return size_; } + + + Block& get(unsigned n) { + assert(n < size_); + assert(loaded_[n]); + return *loaded_[n]; + } + + const Block& get(unsigned n) const { + assert(n < size_); + assert(loaded_[n]); + return *loaded_[n]; + } + + void commit() { + for (unsigned n = 0; n < size_; ++n) + if(loaded_[n]) + commit(n); + } + + void commit(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + ios_.seekp(n * Block::nbytes); + ios_.write(b->bytes, Block::nbytes); + ios_.flush(); + } + + void forget(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + commit(n); + loaded_[n] = 0; + delete b; + } + + void load(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + if (!b) b = new Block; + ios_.seekp(n * Block::nbytes); + ios_.read(b->bytes, Block::nbytes); + loaded_[n] = b; + } + + Block** loaded_; + std::iostream &ios_; + unsigned size_; +}; + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/backend/mmap.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/backend/mmap.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/backend/mmap.hh (revision 1778) @@ -0,0 +1,125 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef mmap_backend_hh +#define mmap_backend_hh + +#include <sys/mman.h> +#include <unistd.h> +#include <cassert> +#include <cstdio> + + +namespace mln +{ + + template<typename Block> + struct mmap_backend : public Object< mmap_backend<Block> >{ + typedef Block block_type; + + mmap_backend(int fd, unsigned n_blocks) + : fd_(fd), size_(n_blocks) { + + assert(Block::nbytes % getpagesize() == 0); + if (fd == -1) { perror("open"); exit(1); } + assert(fd_ != -1); + +#ifndef NDEBUG + // FIXME: should be performed as static check + Block *bl = 0; + assert((void*)bl == (void*)bl->bytes); +#endif + + loaded_ = new Block*[n_blocks]; + for (Block **p = loaded_; p < loaded_ + n_blocks; ++p) + *p = 0; + } + + ~mmap_backend() { + for (unsigned n = 0; n < size_; ++n) + if (loaded_[n]) + munmap(loaded_[n]->bytes, Block::nbytes); + delete[] loaded_; + } + + unsigned size() { return size_; } + + Block& get(unsigned n) { + assert(n < size_); + assert(loaded_[n]); + return *loaded_[n]; + } + + const Block& get(unsigned n) const { + assert(n < size_); + assert(loaded_[n]); + return *loaded_[n]; + } + + void commit() { + for (unsigned n = 0; n < size_; ++n) + if(loaded_[n]) + commit(n); + } + + void commit(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + if (msync(b->bytes, Block::nbytes, MS_SYNC) == -1) + perror("msync"); + } + + void forget(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + loaded_[n] = 0; + if (munmap(b->bytes, Block::nbytes) == -1) + perror("munmap"); + } + + void load(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + if (!b) { + b = (Block*) mmap(0, Block::nbytes, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd_, n * Block::nbytes); + if (b == (void*)-1) + perror("mmap"); + assert(b != 0); + loaded_[n] = b; + + } + } + + Block** loaded_; + int fd_; + unsigned size_; + }; + + +} // end of namespace mln + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/backend/file.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/backend/file.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/backend/file.hh (revision 1778) @@ -0,0 +1,76 @@ +#ifndef file_backend_hh +#define file_backend_hh + +#include <unistd.h> +#include <cassert> + +template<typename Block> +struct file_backend { + typedef Block block_type; + + file_backend(int fd, unsigned n_blocks) + : fd_(fd), size_(n_blocks) { + loaded_ = new Block*[n_blocks]; + for (Block **p = loaded_; p < loaded_ + n_blocks; ++p) + *p = 0; + } + + ~file_backend() { + for (unsigned n = 0; n < size_; ++n) + if (loaded_[n]) { + commit(n); + delete loaded_[n]; + } + delete[] loaded_; + } + + unsigned size() const { return size_; } + + Block& get(unsigned n) { + assert(n < size_); + assert(loaded_[n]); + return *loaded_[n]; + } + + const Block& get(unsigned n) const { + assert(n < size_); + assert(loaded_[n]); + return *loaded_[n]; + } + + void commit() { + for (unsigned n = 0; n < size_; ++n) + if(loaded_[n]) + commit(n); + } + + void commit(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + lseek(fd_, n * Block::nbytes, SEEK_SET); + write(fd_, b->bytes, Block::nbytes); + } + + void forget(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + commit(n); + loaded_[n] = 0; + delete b; + } + + void load(unsigned n) { + assert(n < size_); + Block *b = loaded_[n]; + if (!b) b = new Block; + lseek(fd_, n * Block::nbytes, SEEK_SET); + read(fd_, b->bytes, Block::nbytes); + loaded_[n] = b; + } + + Block** loaded_; + int fd_; + unsigned size_; +}; + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/tiled_image2d.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/tiled_image2d.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/tiled_image2d.hh (revision 1778) @@ -0,0 +1,357 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CORE_TILED_IMAGE2D_HH +# define MLN_CORE_TILED_IMAGE2D_HH + +/*! \file mln/core/tiled_image2d.hh + * + * \brief Definition of the basic mln::tiled_image2d class. + */ + +# include <mln/core/internal/image_primary.hh> +# include <mln/core/internal/fixme.hh> +# include <mln/core/box2d.hh> +# include <mln/core/inplace.hh> +# include <mln/core/init.hh> + +# include <mln/border/thickness.hh> +# include <mln/value/set.hh> +# include <mln/fun/i2v/all_to.hh> +# include <mln/core/line_piter.hh> +# include <fcntl.h> + +# include "support/lru.hh" +# include "backend/mmap.hh" +# include "layout/layout2d.hh" +# include "block.hh" +# include "page.hh" + +// FIXME : give the side's side of the square of the block. +# define SIDE 128 + +namespace mln +{ + + // Fwd decl. + template <typename T> struct tiled_image2d; + + + namespace internal + { + + /// \internal Data structure for \c mln::tiled_image2d<T>. + template <typename T> + struct data_< tiled_image2d<T> > + { + typedef block<T, SIDE * SIDE> block; + typedef mmap_backend<block> backend; + typedef lru_support<backend> support; + typedef layout2d<SIDE, SIDE> layout; + + data_(const box2d& b); + ~data_(); + + void prepare(const point2d& p) { + unsigned page_n = layout::image_layout::page_at(*this, p); + support_.prepare(page_n); + } + + support& support_; + + box2d b_; // theoretical box + unsigned bdr_; + }; + + } // end of namespace mln::internal + + + namespace trait + { + + template <typename T> + struct image_< tiled_image2d<T> > : default_image_< T, tiled_image2d<T> > + { + typedef trait::image::category::primary category; + + typedef trait::image::access::random access; + typedef trait::image::space::two_d space; + typedef trait::image::size::regular size; + typedef trait::image::support::aligned support; + + typedef trait::image::border::stored border; + typedef trait::image::data::linear data; + typedef trait::image::io::read_write io; + typedef trait::image::speed::fast speed; + }; + + } // end of namespace mln::trait + + + + /*! \brief FIXME. + * + * FIXME + */ + template <typename T> + struct tiled_image2d : public internal::image_primary_< box2d, tiled_image2d<T> > + { + // Warning: just to make effective types appear in Doxygen: + typedef box2d pset; + typedef point2d psite; + typedef point2d point; + typedef dpoint2d dpoint; + typedef mln_fwd_piter(box2d) fwd_piter; + typedef mln_bkd_piter(box2d) bkd_piter; + typedef line_piter_<point> line_piter; + // End of warning. + + + /// Value associated type. + typedef T value; + + /// Return type of read-only access. + typedef const T& rvalue; + + /// Return type of read-write access. + typedef T& lvalue; + + + /// Skeleton. + typedef tiled_image2d< tag::value_<T> > skeleton; + + + /// Value_Set associated type. + typedef mln::value::set<T> vset; + + /// Block type. + typedef block<T, SIDE * SIDE> block; + + /// Support type. + typedef lru_support<mmap_backend<block> > support; + /// Layout type + typedef layout2d<SIDE, SIDE> layout; + /// Page type + typedef page<T, layout> page; + + /// Constructor without argument. + tiled_image2d(); + + /// Constructor with the numbers of rows and columns + tiled_image2d(int nrows, int ncols); + + /// Constructor with a box (default is + /// 3). + tiled_image2d(const box2d& b); + + + /// Initialize an empty image. + void init_(const box2d& b); + + + /// Test if \p p is valid. + bool owns_(const point2d& p) const; + + /// Give the set of values of the image. + const vset& values() const; + + /// Give the definition domain. + const box2d& domain() const; + + /// Give the number of cells (points including border ones). + std::size_t ncells() const; + + /// Read-only access to the image value located at point \p p. + const T& operator()(const point2d& p) const; + + /// Read-write access to the image value located at point \p p. + T& operator()(const point2d& p); + + /// Read-only access to the image value located at offset \p o. + const T& operator[](unsigned o) const; + + /// Read-write access to the image value located at offset \p o. + T& operator[](unsigned o); + + /// Read-only access to the image value located at (\p row, \p col). + const T& at(int row, int col) const; + + /// Read-write access to the image value located at (\p row, \p col). + T& at(int row, int col); + + }; + + + + // Fwd decl. + + template <typename T, typename J> + void init_(tag::image_t, mln::tiled_image2d<T>& target, const J& model); + + + +# ifndef MLN_INCLUDE_ONLY + + // init_ + + template <typename T, typename J> + inline + void init_(tag::image_t, tiled_image2d<T>& target, const J& model) + { + box2d b; + init_(tag::bbox, b, model); + unsigned bdr; + target.init_(b); + } + + + // internal::data_< tiled_image2d<T> > + + namespace internal + { + template <typename T> + inline + data_< tiled_image2d<T> >::data_(const box2d& b) + : b_ (b), + // FIXME : hard coded path. + support_(*new support(*new backend( open("/tmp/milena_tiled.image", O_RDWR | O_CREAT | O_TRUNC, 0664), b.npoints()) )) + { + std::cout << b.npoints() * sizeof(T) << std::endl; + char a = 0; + lseek(support_.backend_.fd_, b.npoints() * sizeof(T) - 1, SEEK_SET); + write(support_.backend_.fd_, &a, 1); + } + + template <typename T> + inline + data_< tiled_image2d<T> >::~data_() + { + close(support_.backend_.fd_); + } + + } // end of namespace mln::internal + + + // tiled_image2d<T> + + template <typename T> + inline + tiled_image2d<T>::tiled_image2d() + { + } + + template <typename T> + inline + tiled_image2d<T>::tiled_image2d(int nrows, int ncols) + { + init_(make::box2d(nrows, ncols)); + } + + template <typename T> + inline + tiled_image2d<T>::tiled_image2d(const box2d& b) + { + init_(b); + } + + template <typename T> + inline + void + tiled_image2d<T>::init_(const box2d& b) + { + mln_precondition(! this->has_data()); + this->data_ = new internal::data_< tiled_image2d<T> >(b); + } + + template <typename T> + inline + const typename tiled_image2d<T>::vset& + tiled_image2d<T>::values() const + { + return vset::the(); + } + + template <typename T> + inline + const box2d& + tiled_image2d<T>::domain() const + { + mln_precondition(this->has_data()); + return this->data_->b_; + } + + template <typename T> + inline + std::size_t + tiled_image2d<T>::ncells() const + { + mln_precondition(this->has_data()); + return this->data_->b_.npoints(); + } + + template <typename T> + inline + bool + tiled_image2d<T>::owns_(const point2d& p) const + { + mln_precondition(this->has_data()); + return this->data_->b_.has(p); + } + + template <typename T> + inline + const T& + tiled_image2d<T>::operator()(const point2d& p) const + { + mln_precondition(this->owns_(p)); + unsigned page_n = layout::image_layout::page_at(*this, p); + // note: although the page instance goes + // out of scope, the reference stays valid + // because the block is ultimately held by support. + return page(const_cast<support&>(this->data_->support_).get_block(page_n)) + (layout::image_layout::changeref(p)); + } + + template <typename T> + inline + T& + tiled_image2d<T>::operator()(const point2d& p) + { + mln_precondition(this->owns_(p)); + unsigned page_n = layout::image_layout::page_at(*this, p); + // note: although the page instance goes + // out of scope, the reference stays valid + // because the block is ultimately held by support. + return page(this->data_->support_.get_block(page_n)) + (layout::image_layout::changeref(p)); + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif // ! MLN_CORE_TILED_IMAGE2D_HH Index: trunk/milena/sandbox/garrigues/tiled_image2d/block.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/block.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/block.hh (revision 1778) @@ -0,0 +1,63 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef block_hh +#define block_hh + +#include <cassert> + +namespace mln +{ + + template<typename T, unsigned size> + struct block : public Object< block<T, size> > { + typedef T value_type; + enum { nitems = size, nbytes = size * sizeof(T) }; + union { + char bytes[nbytes]; + T array[nitems]; + }; + + T& operator[](unsigned p) + { + assert(p < nitems); + return array[p]; + } + + const T& operator[](unsigned p) const + { + assert(p < nbytes); + return array[p]; + } + }; + + +} // end of namespace mln + + + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/page.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/page.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/page.hh (revision 1778) @@ -0,0 +1,91 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef page_hh +#define page_hh + +#include "block.hh" + +namespace mln +{ + + template <unsigned Dim, typename Layout> + struct page_domain {}; + + template<typename Layout> + struct page_domain<1, Layout> + { + enum {dim = 1}; + static unsigned len(unsigned) { return Layout::width; } + }; + template<typename Layout> + struct page_domain<2, Layout> + { + enum {dim = 2}; + static unsigned len(unsigned i) { return i ? Layout::height : Layout::width; } + }; + template<typename Layout> + struct page_domain<3, Layout> + { + enum {dim = 3}; + static unsigned len(unsigned i) { + return (i == 2) ? Layout::depth : (i ? Layout::height : Layout::depth); + } + }; + + template<typename T, typename Layout> + struct page : public Object< page<T, Layout> > + { + typedef Layout layout_type; + typedef block<T, Layout::w * Layout::h> block_type; + typedef T value_type; + typedef page_domain<Layout::dim, Layout> domain_type; + + static domain_type domain() + { return domain_type(); } + + page() {} + page(const page& p) : data_(p.data_) {} + page(block_type& p) : data_(&p) {} + + template<typename Point> + value_type& operator()(const Point& p) { + return (*data_)[layout_type::page_layout::pixel_at(p)]; + } + + template<typename Point> + const value_type& operator()(const Point& p) const { + return (*data_)[Layout::page_layout::pixel_at(p)]; + } + + block_type *data_; + }; + + +} // end of namespace mln + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/support/lru.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/support/lru.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/support/lru.hh (revision 1778) @@ -0,0 +1,198 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef lru_support_hh +#define lru_support_hh + +namespace mln +{ + + template<typename Block> + struct item { + item(unsigned n, item<Block>* first) + : block_number(n), prev(0), next(first) + { + if (first) + first->prev = this; + } + + + unsigned block_number; + item<Block> *prev; + item<Block> *next; + }; + +#ifdef LRU_DEBUG +#include <iostream> + + template<typename Item> + struct inspect_ { + inspect_(const Item *first, const Item *last) : first_(first), last_(last) {} + const Item * first_; + const Item * last_; + }; + template<typename Item> + std::ostream& operator<<(std::ostream& o, const inspect_<Item>& i) { + const Item *p = i.first_; + const Item *prev = 0; + while (p) { + assert(p->prev == prev); + o << p << '(' << p->prev << ',' << p->next << ':' << p->block_number << ')' << ' '; + prev = p; + p = p->next; + } + o << i.last_; + return o; + } + template<typename Item> + inspect_<Item> inspect(const Item *first, const Item* last) { return inspect_<Item>(first, last); } +#endif + + /* + LRU: least recently used gets evicted first + */ + template<typename Backend> + struct lru_support : public Object< lru_support<Backend> > { + + typedef typename Backend::block_type block_type; + typedef item<block_type> node_type; + + lru_support(Backend& b, unsigned buffer_size = 5) + : backend_(b), maxitems_(buffer_size), counter_(0), first_(0), last_(0) + { + assert(buffer_size > 1); + unsigned sz = b.size(); + map_ = new node_type* [sz]; + for (node_type **p = map_; p < map_ + sz; ++p) + *p = 0; + } + + ~lru_support() { + delete[] map_; + } + + void hit(node_type* node, unsigned n) { + assert(node->block_number == n); + if (first_ != node) { +#ifdef LRU_DEBUG + std::cerr << "lru: pull " << n << '<' << node << '>' << ' ' << inspect(first_,last_) << std::endl; +#endif + // move to head of queue + + if (node->next) // is last? + // no: patch up next node + node->next->prev = node->prev; + else + // yes + last_ = node->prev; + + // patch up previous node + node->prev->next = node->next; + + // insert in front + first_->prev = node; + node->next = first_; + node->prev = 0; + first_ = node; + +#ifdef LRU_DEBUG + std::cerr << "lru: end pull " << n << ' ' << inspect(first_,last_) << std::endl; +#endif + } + + } + + void evict_last() { + node_type *prev = last_->prev; + +#ifdef LRU_DEBUG + std::cerr << "lru: evict " << last_->block_number << ' ' << inspect(first_, last_) << std::endl; +#endif + backend_.forget(last_->block_number); + + map_[last_->block_number] = 0; + delete last_; + + prev->next = 0; + last_ = prev; + --counter_; + } + + node_type* miss(unsigned n) { +#ifdef LRU_DEBUG + std::cerr << "lru: miss " << n << ' ' << inspect(first_, last_) << std::endl; +#endif + + if (counter_ >= maxitems_) + evict_last(); + +#ifdef LRU_DEBUG + std::cerr << "lru: load " << n << ' ' << inspect(first_, last_) << std::endl; +#endif + + backend_.load(n); + + node_type *node = new node_type(n, first_); + map_[n] = node; + first_ = node; + + if (!last_) + // first item ever, becomes new last + last_ = node; + +#ifdef LRU_DEBUG + std::cerr << "lru: end miss " << n << ' ' << inspect(first_, last_) << std::endl; +#endif + + ++counter_; + return node; + } + + block_type& get_block(unsigned n) { + prepare(n); + return backend_.get(n); + } + + void prepare(unsigned n) { + if (node_type *node = map_[n]) + hit(node, n); + else + miss(n); + } + + Backend& backend_; + unsigned maxitems_; + unsigned counter_; + node_type **map_; + node_type *first_; + node_type *last_; + }; + + +} // end of namespace mln + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/support/simple.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/support/simple.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/support/simple.hh (revision 1778) @@ -0,0 +1,35 @@ +#ifndef simple_support_hh +#define simple_support_hh + +/* +Simple support: only one page in memory at a time. + */ +template<typename Backend> +struct simple_support { + + typedef typename Backend::block_type block_type; + + simple_support(Backend& b) + : backend_(b), current_(0) + { + backend_.load(0); + } + + void prepare(unsigned n) { + // no-op here + } + + block_type& get_block(unsigned n) { + if (n != current_) { + backend_.forget(current_); + backend_.load(n); + current_ = n; + } + return backend_.get(n); + } + + Backend& backend_; + unsigned current_; +}; + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/tiled_image2d.cc =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/tiled_image2d.cc (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/tiled_image2d.cc (revision 1778) @@ -0,0 +1,45 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/*! \file tests/tiled_image2d.cc + * + * \brief Tests on mln::tiled_image2d. + */ + +#include "tiled_image2d.hh" + +#include <mln/level/fill.hh> +#include <mln/debug/println.hh> + +int main() +{ + using namespace mln; + + tiled_image2d<int> ima(10700, 10700); + + level::fill(ima, 6); +} Index: trunk/milena/sandbox/garrigues/tiled_image2d/layout/layout2d.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/layout/layout2d.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/layout/layout2d.hh (revision 1778) @@ -0,0 +1,56 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef layout2d_hh +#define layout2d_hh + +#include "block.hh" +#include "layout/image2d/lrtb.hh" +#include "layout/page2d/lrtb.hh" + +namespace mln +{ + + template<unsigned width, unsigned height, + template<unsigned,unsigned> class ImageLayout = layout::image2d_lrtb, + template<unsigned,unsigned> class PageLayout = layout::page2d_lrtb > + struct layout2d : public Object< layout2d<width, height> > { + enum { dim = 2 , w = width, h = height }; + + typedef ImageLayout<width, height> image_layout; + typedef PageLayout<width, height> page_layout; + + template<typename T> + struct block_ : block<T, width * height> {}; + + }; + + +} // end of namespace mln + + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/tblr.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/tblr.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/tblr.hh (revision 1778) @@ -0,0 +1,21 @@ +#ifndef layout_page2d_tblr_hh +#define layout_page2d_tblr_hh + +#include "ersatz/point.hh" + +namespace layout { + +template<unsigned W, unsigned H> +struct page2d_tblr { + enum { dim = 2, width = W, height = H, nitems = W * H }; + + template<typename C> + static unsigned pixel_at(const point2d_<C>& p) + { + return p[0] * height + p[1]; + } +}; + +} + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/lrtb.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/lrtb.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/lrtb.hh (revision 1778) @@ -0,0 +1,52 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef layout_page2d_lrtb_hh +#define layout_page2d_lrtb_hh + +#include <mln/core/point2d.hh> + +namespace mln +{ + + namespace layout { + + template<unsigned W, unsigned H> + struct page2d_lrtb { + enum { dim = 2, width = W, height = H, nitems = W * H }; + + static unsigned pixel_at(const point2d& p) + { + return p[1] * width + p[0]; + } + }; + + } + +} // end of namespace mln + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/all.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/all.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/layout/page2d/all.hh (revision 1778) @@ -0,0 +1,7 @@ +#ifndef layout_page2d_all_hh +#define layout_page2d_all_hh + +#include "layout/page2d/lrtb.hh" +#include "layout/page2d/tblr.hh" + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/layout/all.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/layout/all.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/layout/all.hh (revision 1778) @@ -0,0 +1,8 @@ +#ifndef layout_all_hh +#define layout_all_hh + +#include "layout/layout2d.hh" +#include "layout/page2d/all.hh" +#include "layout/image2d/all.hh" + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/tblr.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/tblr.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/tblr.hh (revision 1778) @@ -0,0 +1,33 @@ +#ifndef layout_image2d_tblr_hh +#define layout_image2d_tblr_hh + +#include "ersatz/point.hh" + +namespace layout { + +template<unsigned W, unsigned H> +struct image2d_tblr { + enum { dim = 2, page_width = W, page_height = H }; + + template<typename Image> + static unsigned size(const Image& im) { + const typename Image::domain_type& d = im.domain(); + return (d.len(0) / page_width ) * (d.len(1) / page_height); + } + + template<typename Image, typename C> + static unsigned page_at(const Image& im, const point2d_<C>& p) + { + return (p[0] / page_width) * (im.domain().len(1) / page_height) + p[1] / page_height; + }; + + template<typename C> + static point2d_<C> changeref(const point2d_<C>& p) + { + return point2d_<C(p[0] % page_width, p[1] % page_height); + } +}; + +} + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/lrtb.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/lrtb.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/lrtb.hh (revision 1778) @@ -0,0 +1,65 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef layout_image2d_lrtb_hh +#define layout_image2d_lrtb_hh + +#include <mln/core/point2d.hh> + +namespace mln +{ + + namespace layout { + + template<unsigned W, unsigned H> + struct image2d_lrtb : public Object<image2d_lrtb<W, H> > { + enum { dim = 2, page_width = W, page_height = H }; + + template<typename Image> + static unsigned size(const Image& im) { + const typename Image::domain_type& d = im.domain(); + return (d.len(0) / page_width ) * (d.len(1) / page_height); + } + + template<typename Image> + static unsigned page_at(const Image& im, const point2d& p) + { + return (p[1] / page_height) * (im.domain().len(0) / page_width) + p[0] / page_width; + }; + + static point2d changeref(const point2d& p) + { + return point2d(p[0] % page_width, p[1] % page_height); + } + }; + + } + + +} // end of namespace mln + +#endif Index: trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/all.hh =================================================================== --- trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/all.hh (revision 0) +++ trunk/milena/sandbox/garrigues/tiled_image2d/layout/image2d/all.hh (revision 1778) @@ -0,0 +1,7 @@ +#ifndef layout_image2d_all_hh +#define layout_image2d_all_hh + +#include "layout/image2d/lrtb.hh" +#include "layout/image2d/tblr.hh" + +#endif