new sat::Map - Libsolv (bit)Map wrapper.
authorMichael Andres <ma@suse.de>
Fri, 13 Jan 2012 13:55:31 +0000 (14:55 +0100)
committerMichael Andres <ma@suse.de>
Fri, 13 Jan 2012 13:55:31 +0000 (14:55 +0100)
tests/sat/CMakeLists.txt
tests/sat/Map_test.cc [new file with mode: 0644]
zypp/CMakeLists.txt
zypp/sat/Map.cc [new file with mode: 0644]
zypp/sat/Map.h [new file with mode: 0644]

index 7b2d657..aa09fe5 100644 (file)
@@ -7,6 +7,7 @@ ADD_TESTS(
   IdString
   LookupAttr
   Pool
+  Map
   Solvable
   SolvParsing
   WhatObsoletes
diff --git a/tests/sat/Map_test.cc b/tests/sat/Map_test.cc
new file mode 100644 (file)
index 0000000..a6ec55b
--- /dev/null
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <iostream>
+#include <boost/test/auto_unit_test.hpp>
+
+#include "zypp/base/LogTools.h"
+#include "zypp/base/Easy.h"
+#include "zypp/sat/Map.h"
+
+
+#define BOOST_TEST_MODULE Map
+
+using std::endl;
+using std::cout;
+using namespace zypp;
+using namespace boost::unit_test;
+
+
+BOOST_AUTO_TEST_CASE(basic)
+{
+  sat::Map m;
+  BOOST_CHECK_EQUAL( m.empty(), true );
+  BOOST_CHECK_EQUAL( m.size(), 0 );
+  BOOST_CHECK_EQUAL( m.asString(), "" );
+  BOOST_CHECK( m == sat::Map() );
+
+  m.grow( 8 );
+  BOOST_CHECK_EQUAL( m.empty(), false );
+  BOOST_CHECK_EQUAL( m.size(), 8 );
+  BOOST_CHECK_EQUAL( m.asString(), "00000000" );
+  BOOST_CHECK( m != sat::Map() );
+
+  m.grow( 9 );
+  BOOST_CHECK_EQUAL( m.empty(), false );
+  BOOST_CHECK_EQUAL( m.size(), 16 );
+  BOOST_CHECK_EQUAL( m.asString(), "0000000000000000" );
+
+  m.grow( 0 ); // no shrink!
+  BOOST_CHECK_EQUAL( m.size(), 16 );
+
+  m.setAll();
+  BOOST_CHECK_EQUAL( m.asString(), "1111111111111111" );
+
+  m.clear( 0 );
+  m.assign( 3, false );
+  BOOST_CHECK_EQUAL( m.asString(), "0110111111111111" );
+  BOOST_CHECK_EQUAL( m.test( 0 ), false );
+  BOOST_CHECK_EQUAL( m.test( 1 ), true );
+
+  // COW
+  m.clearAll();
+  sat::Map n(m);
+  BOOST_CHECK_EQUAL( m.asString(), "0000000000000000" );
+  BOOST_CHECK_EQUAL( n.asString(), "0000000000000000" );
+  BOOST_CHECK_EQUAL( m, n );
+
+  m.set( 1 );
+  BOOST_CHECK_EQUAL( m.asString(), "0100000000000000" );
+  BOOST_CHECK_EQUAL( n.asString(), "0000000000000000" );
+  BOOST_CHECK( m != n );
+
+  n.set( 1 );
+  BOOST_CHECK_EQUAL( m.asString(), "0100000000000000" );
+  BOOST_CHECK_EQUAL( n.asString(), "0100000000000000" );
+  BOOST_CHECK( m == n );
+
+
+  BOOST_CHECK_THROW( m.set( 99 ), std::out_of_range );
+}
index db4d53f..a2ecac1 100644 (file)
@@ -528,6 +528,7 @@ SET( zypp_sat_SRCS
   sat/Solvable.cc
   sat/SolvableSet.cc
   sat/SolvIterMixin.cc
+  sat/Map.cc
   sat/Queue.cc
   sat/Transaction.cc
   sat/WhatProvides.cc
@@ -543,7 +544,8 @@ SET( zypp_sat_HEADERS
   sat/Solvable.h
   sat/SolvableSet.h
   sat/SolvIterMixin.h
-  sat/Queue.cc
+  sat/Map.h
+  sat/Queue.h
   sat/Transaction.h
   sat/WhatProvides.h
   sat/WhatObsoletes.h
diff --git a/zypp/sat/Map.cc b/zypp/sat/Map.cc
new file mode 100644 (file)
index 0000000..f63b250
--- /dev/null
@@ -0,0 +1,130 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/sat/Map.cc
+ */
+extern "C"
+{
+#include <solv/bitmap.h>
+}
+#include <iostream>
+#include <exception>
+#include "zypp/base/LogTools.h"
+#include "zypp/base/String.h"
+
+#include "zypp/sat/Map.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+  template<>
+  struct ::_Map * rwcowClone<struct ::_Map>( const struct ::_Map * rhs )
+  {
+    struct ::_Map * ret = new ::_Map;
+    ::map_init_clone( ret, const_cast<struct ::_Map *>(rhs) );
+    return ret;
+  }
+
+  ///////////////////////////////////////////////////////////////////
+  namespace sat
+  { /////////////////////////////////////////////////////////////////
+
+    Map::Map()
+      : _pimpl( new ::_Map )
+    { ::map_init( _pimpl.get(), 0 ); }
+
+    Map::Map( size_type size_r )
+      : _pimpl( new ::_Map )
+    { ::map_init( _pimpl.get(), size_r ); }
+
+    Map::~Map()
+    { ::map_free( _pimpl.get() ); }
+
+    bool Map::empty() const
+    { return( _pimpl->size == 0 ); }
+
+    Map::size_type Map::size() const
+    { return _pimpl->size << 3; }
+
+    void Map::grow( size_type size_r )
+    { ::map_grow( _pimpl.get(), size_r ); }
+
+    void Map::setAll()
+    { assignAll( true ); }
+
+    void Map::clearAll()
+    { assignAll( false ); }
+
+    void Map::assignAll( bool val_r )
+    {
+      if ( _pimpl->size )
+       ::memset( _pimpl->map, (val_r?-1:0), _pimpl->size );
+    }
+
+#define M_RANGE_CKECK(IDX,LOC) if ( ((IDX) >> 3) >= _pimpl->size ) throw std::out_of_range( "zypp::sat::Map::" LOC )
+
+    void Map::set( size_type idx_r )
+    {
+      M_RANGE_CKECK( idx_r, "set" );
+      MAPSET( _pimpl, idx_r );
+    }
+
+    void Map::clear( size_type idx_r )
+    {
+      M_RANGE_CKECK( idx_r, "clear" );
+      MAPCLR( _pimpl, idx_r );
+    }
+
+    void Map::assign( size_type idx_r, bool val_r )
+    {
+      M_RANGE_CKECK( idx_r, "assign" );
+      if ( val_r )
+      { MAPSET( _pimpl, idx_r ); }
+      else
+      { MAPCLR( _pimpl, idx_r ); }
+    }
+
+    bool Map::test( size_type idx_r ) const
+    {
+      M_RANGE_CKECK( idx_r, "test" );
+      return MAPTST( _pimpl, idx_r );
+    }
+
+    std::string Map::asString( const char on_r, const char off_r ) const
+    {
+      if ( empty() )
+       return std::string();
+
+      std::string ret( size(), off_r );
+      for_( idx, size_type(0), size() )
+      {
+       if ( test( idx ) )
+         ret[idx] = on_r;
+      }
+      return ret;
+    }
+
+    Map::operator struct ::_Map *()    // COW: nonconst version can't be inlined
+    { return _pimpl.get(); }           // without exposing struct ::_Map
+
+    bool operator==( const Map & lhs, const Map & rhs )
+    {
+      const struct ::_Map * l = lhs;
+      const struct ::_Map * r = rhs;
+      return( l == r || ( l->size == r->size && ::memcmp( l->map, r->map, l->size ) == 0 ) );
+    }
+
+    /////////////////////////////////////////////////////////////////
+  } // namespace sat
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/sat/Map.h b/zypp/sat/Map.h
new file mode 100644 (file)
index 0000000..ddf587e
--- /dev/null
@@ -0,0 +1,119 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/sat/Map.h
+ */
+#ifndef ZYPP_SAT_MAP_H
+#define ZYPP_SAT_MAP_H
+
+extern "C"
+{
+  struct _Map;
+}
+#include <iosfwd>
+#include <string>
+
+#include "zypp/base/PtrTypes.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{
+  ///////////////////////////////////////////////////////////////////
+  namespace sat
+  {
+    ///////////////////////////////////////////////////////////////////
+    /// \class Map
+    /// \brief Libsolv (bit)Map wrapper.
+    ///
+    /// \Note Requested sizes are filled up to the next multiple of eight.
+    /// Libsolv bitmaps are not shrinkable.
+    ///////////////////////////////////////////////////////////////////
+    class Map
+    {
+    public:
+      typedef unsigned long size_type;
+
+    public:
+      /** Default ctor: empty Map */
+      Map();
+
+      /** Ctor taking the Map size */
+      explicit Map( size_type size_r );
+
+      /** Dtor */
+      ~Map();
+
+    public:
+      /** Whether Map is empty. */
+      bool empty() const;
+
+      /** Size of the Map. */
+      size_type size() const;
+
+      /** Grow the Map if necessary. */
+      void grow( size_type size_r );
+
+    public:
+      /** Set all bits. */
+      void setAll();
+
+      /** Clear all bits. */
+      void clearAll();
+
+      /** Assign \c val_r to all bits. */
+      void assignAll( bool val_r );
+
+      /** Set bit \c idx_r. */
+      void set( size_type idx_r );
+
+      /** Clear bit \c idx_r. */
+      void clear( size_type idx_r );
+
+      /** Assign \c val_r to bit \c idx_r. */
+      void assign( size_type idx_r, bool val_r );
+
+    public:
+      /** Test bit \c idx_r.*/
+      bool test( size_type idx_r ) const;
+
+      /** Test bit \c idx_r.*/
+      bool operator[]( size_type idx_r ) const
+      { return test( idx_r ); }
+
+    public:
+      /** String representation */
+      std::string asString( const char on_r = '1', const char off_r = '0' ) const;
+
+    public:
+      operator struct ::_Map *();              ///< libsolv backdoor
+      operator const struct ::_Map *() const   ///< libsolv backdoor
+      { return _pimpl.get(); }
+    private:
+      RWCOW_pointer<struct ::_Map> _pimpl;     ///< Pointer to implementation
+    };
+
+    /** \relates Map Stream output */
+    inline std::ostream & operator<<( std::ostream & str, const Map & obj )
+    { return str << obj.asString(); }
+
+    /** \relates Map */
+    bool operator==( const Map & lhs, const Map & rhs );
+
+    /** \relates Map */
+    inline bool operator!=( const Map & lhs, const Map & rhs )
+    { return !( lhs == rhs ); }
+
+  } // namespace sat
+  ///////////////////////////////////////////////////////////////////
+
+  /** \relates Map Clone function for RWCOW_pointer */
+  template<> struct ::_Map * rwcowClone<struct ::_Map>( const struct ::_Map * rhs );
+
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_SAT_MAP_H