diff --git a/src/article/preference.cpp b/src/article/preference.cpp index 52d9e4b32..9b54a3e32 100644 --- a/src/article/preference.cpp +++ b/src/article/preference.cpp @@ -14,8 +14,9 @@ #include "cache.h" #include "command.h" -#include #include +#include +#include using namespace ARTICLE; @@ -133,35 +134,30 @@ Preferences::Preferences( Gtk::Window* parent, const std::string& url, const std std::list< std::string > list_id = DBTREE::get_abone_list_id( get_url() ); for( it = list_id.begin(); it != list_id.end(); ++it ) if( ! ( *it ).empty() ) str_id += ( *it ) + "\n"; m_edit_id.set_text( str_id ); - // あぼーんレス番号 // 連番は 12-34 の様なフォーマットに変換 - std::vector< char > vec_res = DBTREE::get_abone_vec_res( get_url() ); - std::vector< char >::iterator it_res = vec_res.begin(); - int res = 0; + const std::unordered_set< int >& set_res = DBTREE::get_abone_reses( get_url() ); + // レス番号をソートする + const std::set< int > tmp_set{ set_res.begin(), set_res.end() }; int pre_res = 0; - int count = 0; - for( ; it_res != vec_res.end(); ++res ){ - - if( ( *it_res ) ){ - if( ! pre_res ) pre_res = res; - ++count; + int save = 0; + for( const int res : tmp_set ) { + if( !pre_res ) { + pre_res = save = res; } - - ++it_res; - - if( !( *it_res ) || it_res == vec_res.end() ){ - - if( pre_res ){ - str_res += MISC::itostr( pre_res ); - if( count > 1 ) str_res += "-" + MISC::itostr( pre_res + count -1 ); - str_res += "\n"; - pre_res = 0; - count = 0; - } + else if( res - pre_res > 1 ) { + str_res.append( std::to_string( save ) ); + if( pre_res != save ) str_res.append( '-' + std::to_string( pre_res ) ); + str_res.push_back( '\n' ); + save = res; } + pre_res = res; + } + if( !tmp_set.empty() ) { + str_res.append( std::to_string( save ) ); + if( pre_res != save ) str_res.append( '-' + std::to_string( pre_res ) ); + str_res.push_back( '\n' ); } - m_edit_res.set_text( str_res ); diff --git a/src/dbtree/articlebase.cpp b/src/dbtree/articlebase.cpp index 8bc7a45f7..690311810 100644 --- a/src/dbtree/articlebase.cpp +++ b/src/dbtree/articlebase.cpp @@ -570,11 +570,7 @@ void ArticleBase::update_writetime() // int ArticleBase::get_num_posted() { - if( ! m_vec_posted.size() ) return 0; - - int ret = 0; - for( int i = 1; i < MAX_RESNUMBER; ++i ) if( is_posted( i ) ) ++ret; - return ret; + return m_posts.size(); } @@ -662,7 +658,7 @@ void ArticleBase::update_abone() // nodetreeが作られていないときは更新しない if( ! m_nodetree ) return; - get_nodetree()->copy_abone_info( m_list_abone_id, m_list_abone_name, m_list_abone_word, m_list_abone_regex, m_vec_abone_res, + get_nodetree()->copy_abone_info( m_list_abone_id, m_list_abone_name, m_list_abone_word, m_list_abone_regex, m_abone_reses, m_abone_transparent, m_abone_chain, m_abone_age, m_abone_board, m_abone_global ); get_nodetree()->update_abone_all(); @@ -704,11 +700,13 @@ void ArticleBase::reset_abone( const std::list< std::string >& ids, if( vec_abone_res.size() ){ - if( ! m_vec_abone_res.size() ) m_vec_abone_res.resize( MAX_RESNUMBER ); - for( int i = 1; i <= MIN( m_number_load, (int)vec_abone_res.size() ) ; ++i ){ - if( vec_abone_res[ i ] ) m_vec_abone_res[ i ] = true; - else m_vec_abone_res[ i ] = false; + if( vec_abone_res[ i ] ) { + m_abone_reses.insert( i ); + } + else { + m_abone_reses.erase( i ); + } } } @@ -801,9 +799,12 @@ void ArticleBase::set_abone_res( const int num_from, const int num_to, const boo std::cout << "ArticleBase::set_abone_res num_from = " << num_from << " num_to = " << num_to << " set = " << set << std::endl; #endif - if( ! m_vec_abone_res.size() ) m_vec_abone_res.resize( MAX_RESNUMBER ); - - for( int i = num_from; i <= num_to; ++i ) m_vec_abone_res[ i ] = set; + if( set ) { + for( int i = num_from; i <= num_to; ++i ) m_abone_reses.insert( i ); + } + else { + for( int i = num_from; i <= num_to; ++i ) m_abone_reses.erase( i ); + } update_abone(); @@ -892,11 +893,7 @@ void ArticleBase::set_abone_global( const bool set ) // int ArticleBase::get_num_bookmark() { - if( ! m_vec_bookmark.size() ) return 0; - - int ret = 0; - for( int i = 1; i < MAX_RESNUMBER; ++i ) if( is_bookmarked( i ) ) ++ret; - return ret; + return m_bookmarks.size(); } @@ -908,11 +905,9 @@ bool ArticleBase::is_bookmarked( const int number ) if( number <= 0 || number > m_number_load ) return false; // まだnodetreeが作られてなくてブックマークの情報が得られてないのでnodetreeを作って情報取得 - if( ! m_vec_bookmark.size() ) get_nodetree(); - - if( ! m_vec_bookmark.size() ) return false; + if( m_bookmarks.empty() ) get_nodetree(); - return ( m_vec_bookmark[ number ] ); + return ( m_bookmarks.find( number ) != m_bookmarks.end() ); } @@ -921,13 +916,16 @@ bool ArticleBase::is_bookmarked( const int number ) // void ArticleBase::set_bookmark( const int number, const bool set ) { - if( ! m_vec_bookmark.size() ) get_nodetree(); + if( m_bookmarks.empty() ) get_nodetree(); if( number <= 0 || number > MAX_RESNUMBER ) return; - if( ! m_vec_bookmark.size() ) m_vec_bookmark.resize( MAX_RESNUMBER ); - m_save_info = true; - m_vec_bookmark[ number ] = set; + if( set ) { + m_bookmarks.insert( number ); + } + else { + m_bookmarks.erase( number ); + } } @@ -939,11 +937,9 @@ bool ArticleBase::is_posted( const int number ) if( number <= 0 || number > m_number_load ) return false; // まだnodetreeが作られてなくて情報が得られてないのでnodetreeを作って情報取得 - if( ! m_vec_posted.size() ) get_nodetree(); - - if( ! m_vec_posted.size() ) return false; + if( m_posts.empty() ) get_nodetree(); - return ( m_vec_posted[ number ] ); + return ( m_posts.find( number ) != m_posts.end() ); } @@ -960,12 +956,15 @@ void ArticleBase::set_posted( const int number, const bool set ) if( number <= 0 || number > m_number_load ) return; // まだnodetreeが作られてなくて情報が得られてないのでnodetreeを作って情報取得 - if( ! m_vec_posted.size() ) get_nodetree(); - - if( ! m_vec_posted.size() ) m_vec_posted.resize( MAX_RESNUMBER ); + if( m_posts.empty() ) get_nodetree(); m_save_info = true; - m_vec_posted[ number ] = set; + if( set ) { + m_posts.insert( number ); + } + else { + m_posts.erase( number ); + } // nodetreeに情報反映 m_nodetree->set_posted( number, set ); @@ -979,14 +978,14 @@ void ArticleBase::clear_post_history() if( ! is_cached() ) return; read_info(); - if( m_vec_posted.size() || m_write_time.tv_sec || m_write_time.tv_usec ){ + if( !m_posts.empty() || m_write_time.tv_sec || m_write_time.tv_usec ){ #ifdef _DEBUG - std::cout << "ArticleBase::clear_post_history size = " << m_vec_posted.size() + std::cout << "ArticleBase::clear_post_history size = " << m_posts.size() << " time = " << m_write_time_date << " subject = " << m_subject << std::endl; #endif - m_vec_posted.clear(); + m_posts.clear(); memset( &m_write_time, 0, sizeof( struct timeval ) ); m_write_time_date = std::string(); @@ -1024,11 +1023,11 @@ JDLIB::ConstPtr< NodeTreeBase >& ArticleBase::get_nodetree() assert( m_nodetree ); // あぼーん情報のコピー - m_nodetree->copy_abone_info( m_list_abone_id, m_list_abone_name, m_list_abone_word, m_list_abone_regex, m_vec_abone_res, + m_nodetree->copy_abone_info( m_list_abone_id, m_list_abone_name, m_list_abone_word, m_list_abone_regex, m_abone_reses, m_abone_transparent, m_abone_chain, m_abone_age, m_abone_board, m_abone_global ); // 書き込み情報のコピー - m_nodetree->copy_post_info( m_vec_posted ); + m_nodetree->copy_post_info( m_posts ); m_nodetree->sig_updated().connect( sigc::mem_fun( *this, &ArticleBase::slot_node_updated ) ); m_nodetree->sig_finished().connect( sigc::mem_fun( *this, &ArticleBase::slot_load_finished ) ); @@ -1374,17 +1373,22 @@ void ArticleBase::slot_load_finished() else m_number_new = 0; // 書き込み情報 - if( m_number_new && m_nodetree->get_vec_posted().size() ){ - - if( ! m_vec_posted.size() ) m_vec_posted.resize( MAX_RESNUMBER ); + const auto& node_posts = m_nodetree->get_posts(); + if( m_number_new && node_posts.size() ) { + const auto end = m_posts.end(); + const auto node_end = node_posts.end(); + (void)end; // _DEBUGが定義されていないときの警告抑制 for( int i = m_number_before_load +1; i <= m_number_load; ++i ){ - if( m_nodetree->get_vec_posted()[ i ] ) m_vec_posted[ i ] = true; - else m_vec_posted[ i ] = false; - + if( node_posts.find( i ) != node_end ) { + m_posts.insert( i ); + } + else { + m_posts.erase( i ); + } #ifdef _DEBUG - if( m_vec_posted[ i ] ) std::cout << "posted no = " << i << std::endl; + if( m_posts.find( i ) != end ) std::cout << "posted no = " << i << std::endl; #endif } } @@ -1711,13 +1715,13 @@ void ArticleBase::delete_cache( const bool cache_only ) m_write_fixname = false; m_write_fixmail = false; - m_vec_bookmark.clear(); - m_vec_posted.clear(); + m_bookmarks.clear(); + m_posts.clear(); m_list_abone_id.clear(); m_list_abone_name.clear(); m_list_abone_word.clear(); m_list_abone_regex.clear(); - m_vec_abone_res.clear(); + m_abone_reses.clear(); m_abone_transparent = false; m_abone_chain = false; m_abone_age = false; @@ -1890,14 +1894,11 @@ void ArticleBase::read_info() GET_INFOVALUE( str_tmp, "bookmark = " ); if( ! str_tmp.empty() ){ - if( ! m_vec_bookmark.size() ) m_vec_bookmark.resize( MAX_RESNUMBER ); - list_tmp = MISC::split_line( str_tmp ); - it_tmp = list_tmp.begin(); - for( ; it_tmp != list_tmp.end(); ++it_tmp ){ - int number = atoi( (*it_tmp).c_str() ); - if( !(*it_tmp).empty() ) m_vec_bookmark[ number ] = true; - else m_vec_bookmark[ number ] = false; + for( const std::string& num_str : list_tmp ) { + if( !num_str.empty() ) { + m_bookmarks.insert( std::stoi( num_str ) ); + } } } @@ -1920,18 +1921,15 @@ void ArticleBase::read_info() if( ! str_tmp.empty() ) m_abone_chain = atoi( str_tmp.c_str() ); // レス番号あぼーん - m_vec_abone_res.clear(); + m_abone_reses.clear(); GET_INFOVALUE( str_tmp, "aboneres = " ); if( ! str_tmp.empty() ){ - if( ! m_vec_abone_res.size() ) m_vec_abone_res.resize( MAX_RESNUMBER ); - list_tmp = MISC::split_line( str_tmp ); - it_tmp = list_tmp.begin(); - for( ; it_tmp != list_tmp.end(); ++it_tmp ){ - int number = atoi( (*it_tmp).c_str() ); - if( !(*it_tmp).empty() ) m_vec_abone_res[ number ] = true; - else m_vec_abone_res[ number ] = false; + for( const std::string& num_str : list_tmp ) { + if( !num_str.empty() ) { + m_abone_reses.insert( std::stoi( num_str ) ); + } } } @@ -1944,14 +1942,11 @@ void ArticleBase::read_info() GET_INFOVALUE( str_tmp, "posted = " ); if( ! str_tmp.empty() ){ - if( ! m_vec_posted.size() ) m_vec_posted.resize( MAX_RESNUMBER ); - list_tmp = MISC::split_line( str_tmp ); - it_tmp = list_tmp.begin(); - for( ; it_tmp != list_tmp.end(); ++it_tmp ){ - int number = atoi( (*it_tmp).c_str() ); - if( !(*it_tmp).empty() ) m_vec_posted[ number ] = true; - else m_vec_posted[ number ] = false; + for( const std::string& num_str : list_tmp ) { + if( !num_str.empty() ) { + m_posts.insert( std::stoi( num_str ) ); + } } } @@ -2052,21 +2047,29 @@ void ArticleBase::read_info() std::cout << "abone-regex\n"; it = m_list_abone_regex.begin(); for( ; it != m_list_abone_regex.end(); ++it ) std::cout << (*it) << std::endl; - if( m_vec_abone_res.size() ){ + if( !m_abone_reses.empty() ) { std::cout << "abone-res ="; - for( int i = 1; i <= m_number_load; ++i ) if( m_vec_abone_res[ i ] ) std::cout << " " << i; - std::cout << std::endl; + const auto end = m_abone_reses.end(); + for( int i = 1; i <= m_number_load; ++i ) { + if( m_abone_reses.find( i ) != end ) std::cout << ' ' << i; + } } - if( m_vec_bookmark.size() ){ - std::cout << "bookmark ="; - for( int i = 1; i <= m_number_load; ++i ) if( m_vec_bookmark[ i ] ) std::cout << " " << i; + if( !m_bookmarks.empty() ) { + std::cout << "bookmark = "; + const auto end = m_bookmarks.end(); + for( int i = 1; i <= m_number_load; ++i ) { + if( m_bookmarks.find( i ) != end ) std::cout << ' ' << i; + } std::cout << std::endl; } - if( m_vec_posted.size() ){ + if( !m_posts.empty() ) { std::cout << "posted ="; - for( int i = 1; i <= m_number_load; ++i ) if( m_vec_posted[ i ] ) std::cout << " " << i; + const auto end = m_posts.end(); + for( int i = 1; i <= m_number_load; ++i ) { + if( m_posts.find( i ) != end ) std::cout << ' ' << i; + } std::cout << std::endl; } #endif @@ -2119,20 +2122,29 @@ void ArticleBase::save_info( const bool force ) // レスあぼーん std::ostringstream ss_abone_res; - if( m_vec_abone_res.size() ){ - for( int i = 1; i <= m_number_load; ++i ) if( m_vec_abone_res[ i ] ) ss_abone_res << " " << i; + if( !m_abone_reses.empty() ) { + const auto end = m_abone_reses.end(); + for( int i = 1; i <= m_number_load; ++i ) { + if( m_abone_reses.find( i ) != end ) ss_abone_res << ' ' << i; + } } // レスのブックマーク std::ostringstream ss_bookmark; - if( m_vec_bookmark.size() ){ - for( int i = 1; i <= m_number_load; ++i ) if( m_vec_bookmark[ i ] ) ss_bookmark << " " << i; + if( !m_bookmarks.empty() ) { + const auto end = m_bookmarks.end(); + for( int i = 1; i <= m_number_load; ++i ) { + if( m_bookmarks.find( i ) != end ) ss_bookmark << ' ' << i; + } } // 書き込み std::ostringstream ss_posted; - if( m_vec_posted.size() ){ - for( int i = 1; i <= m_number_load; ++i ) if( m_vec_posted[ i ] ) ss_posted << " " << i; + if( !m_posts.empty() ) { + const auto end = m_posts.end(); + for( int i = 1; i <= m_number_load; ++i ) { + if( m_posts.find( i ) != end ) ss_posted << ' ' << i; + } } std::ostringstream sstr; diff --git a/src/dbtree/articlebase.h b/src/dbtree/articlebase.h index 0190ffa49..2e327f2a2 100644 --- a/src/dbtree/articlebase.h +++ b/src/dbtree/articlebase.h @@ -9,16 +9,17 @@ #ifndef _ARTICLEBASE_H #define _ARTICLEBASE_H -#include -#include -#include -#include -#include - #include "skeleton/lockable.h" #include "jdlib/constptr.h" +#include +#include +#include +#include +#include +#include + namespace DBTREE { class NodeTreeBase; @@ -74,7 +75,7 @@ namespace DBTREE std::list< std::string > m_list_abone_name; // あぼーんする名前 std::list< std::string > m_list_abone_word; // あぼーんする文字列 std::list< std::string > m_list_abone_regex; // あぼーんする正規表現 - std::vector< char > m_vec_abone_res; // レスあぼーん情報 + std::unordered_set< int > m_abone_reses; // レスあぼーん情報 bool m_abone_transparent; // 透明あぼーん bool m_abone_chain; // 連鎖あぼーん bool m_abone_age; // age ているレスをあぼーん @@ -85,10 +86,10 @@ namespace DBTREE bool m_bookmarked_thread; // 「レス」のブックマーク - std::vector< char > m_vec_bookmark; // ブックマーク判定キャッシュ + std::unordered_set< int > m_bookmarks; // ブックマーク判定キャッシュ // 自分が書き込んだレスか - std::vector< char > m_vec_posted; + std::unordered_set< int > m_posts; // HDDにキャッシュされているか bool m_cached; @@ -317,7 +318,7 @@ namespace DBTREE const std::list< std::string >& get_abone_list_name(){ return m_list_abone_name; } const std::list< std::string >& get_abone_list_word(){ return m_list_abone_word; } const std::list< std::string >& get_abone_list_regex(){ return m_list_abone_regex; } - const std::vector< char >& get_abone_vec_res(){ return m_vec_abone_res; } + const std::unordered_set< int >& get_abone_reses() const noexcept { return m_abone_reses; } // 透明 bool get_abone_transparent(); diff --git a/src/dbtree/interface.cpp b/src/dbtree/interface.cpp index 26a63a5b0..cd3ae9309 100644 --- a/src/dbtree/interface.cpp +++ b/src/dbtree/interface.cpp @@ -1169,9 +1169,9 @@ const std::list< std::string >& DBTREE::get_abone_list_regex( const std::string& } -const std::vector< char >& DBTREE::get_abone_vec_res( const std::string& url ) +const std::unordered_set< int >& DBTREE::get_abone_reses( const std::string& url ) { - return DBTREE::get_article( url )->get_abone_vec_res(); + return DBTREE::get_article( url )->get_abone_reses(); } diff --git a/src/dbtree/interface.h b/src/dbtree/interface.h index 8e7462cd9..f4241c365 100644 --- a/src/dbtree/interface.h +++ b/src/dbtree/interface.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace XML @@ -326,7 +327,7 @@ namespace DBTREE const std::list< std::string >& get_abone_list_thread_remove( const std::string& url ); const std::list< std::string >& get_abone_list_word_thread( const std::string& url ); const std::list< std::string >& get_abone_list_regex_thread( const std::string& url ); - const std::vector< char >& get_abone_vec_res( const std::string& url ); + const std::unordered_set< int >& get_abone_reses( const std::string& url ); int get_abone_number_thread( const std::string& url ); int get_abone_hour_thread( const std::string& url ); diff --git a/src/dbtree/nodetreebase.cpp b/src/dbtree/nodetreebase.cpp index fb7fb2f10..91b05c1e8 100644 --- a/src/dbtree/nodetreebase.cpp +++ b/src/dbtree/nodetreebase.cpp @@ -1646,8 +1646,7 @@ const char* NodeTreeBase::add_one_dat_line( const char* datline ) const bool hit = MESSAGE::get_log_manager()->check_write( m_url, newthread, m_buffer_write, 0 ); if( hit ){ - if( ! m_vec_posted.size() ) m_vec_posted.resize( MAX_RESNUMBER ); - m_vec_posted[ header->id_header ] = true; + m_posts.insert( header->id_header ); } #ifdef _DEBUG @@ -2821,7 +2820,7 @@ void NodeTreeBase::copy_abone_info( const std::list< std::string >& list_abone_i const std::list< std::string >& list_abone_name, const std::list< std::string >& list_abone_word, const std::list< std::string >& list_abone_regex, - const std::vector< char >& vec_abone_res, + const std::unordered_set< int >& abone_reses, const bool abone_transparent, const bool abone_chain, const bool abone_age, const bool abone_board, const bool abone_global ) { @@ -2843,7 +2842,7 @@ void NodeTreeBase::copy_abone_info( const std::list< std::string >& list_abone_i m_list_abone_word_global = MISC::replace_str_list( CONFIG::get_list_abone_word(), "\\n", "\n" ); m_list_abone_regex_global = MISC::replace_str_list( CONFIG::get_list_abone_regex(), "\\n", "\n" ); - m_vec_abone_res = vec_abone_res; + m_abone_reses = abone_reses; if( CONFIG::get_abone_transparent() ) m_abone_transparent = true; else m_abone_transparent = abone_transparent; @@ -2908,8 +2907,7 @@ void NodeTreeBase::update_abone( const int from_number, const int to_number ) // bool NodeTreeBase::check_abone_res( const int number ) { - if( ! m_vec_abone_res.size() ) return false; - if( ! m_vec_abone_res[ number ] ) return false; + if( m_abone_reses.find( number ) == m_abone_reses.end() ) return false; NODE* head = res_header( number ); if( ! head ) return false; @@ -3259,10 +3257,10 @@ void NodeTreeBase::check_reference( const int number ) if( head->headinfo->abone ) return; // 2重チェック防止用 - bool checked[ MAX_RESNUMBER ]; - memset( checked, 0, sizeof( bool ) * MAX_RESNUMBER ); + std::unordered_set< int > checked; + checked.reserve( m_id_header +1 ); - const bool posted = m_vec_posted.size(); + const bool posted = !m_posts.empty(); // 過去のレスから number 番へのアンカーがあった場合 if( m_map_future_refer.size() ){ @@ -3278,7 +3276,7 @@ void NodeTreeBase::check_reference( const int number ) std::cout << "found number = " << number << " size = " << size << std::endl; #endif // 過去のレスへ自分の書き込みへの参照マークを付ける - if( posted && m_vec_posted[ number ] ){ + if( posted && m_posts.find( number ) != m_posts.end() ) { for( int i = 0; i < size; ++ i ){ @@ -3288,8 +3286,7 @@ void NodeTreeBase::check_reference( const int number ) #endif NODE* tmphead = res_header( from ); if( tmphead && ! tmphead->headinfo->abone ){ - if( ! m_vec_refer_posted.size() ) m_vec_refer_posted.resize( MAX_RESNUMBER ); - m_vec_refer_posted[ from ] = true; + m_refer_posts.insert( from ); } } } @@ -3331,7 +3328,7 @@ void NodeTreeBase::check_reference( const int number ) for( int i = anc_from; i <= anc_to ; ++i ){ // 既にチェックしている - if( checked[ i ] ) continue; + if( checked.find( i ) != checked.end() ) continue; // 自分自身 if( i == number ) continue; @@ -3370,12 +3367,11 @@ void NodeTreeBase::check_reference( const int number ) && tmphead->headinfo->block[ BLOCK_NUMBER ] ){ - checked[ i ] = true; + checked.insert( i ); // 自分の書き込みに対するレス - if( posted && m_vec_posted[ i ] ){ - if( ! m_vec_refer_posted.size() ) m_vec_refer_posted.resize( MAX_RESNUMBER ); - m_vec_refer_posted[ number ] = true; + if( posted && m_posts.find( i ) != m_posts.end() ) { + m_refer_posts.insert( number ); #ifdef _DEBUG std::cout << "ref " << i << " from " << number << std::endl; @@ -3635,37 +3631,33 @@ int NodeTreeBase::convert_amp( char* text, const int n ) // 自分の書き込みにレスしたか bool NodeTreeBase::is_refer_posted( const int number ) { - if( ! m_vec_refer_posted.size() ) return false; - if( m_vec_refer_posted.size() <= ( size_t )number ) return false; - - return m_vec_refer_posted[ number ]; + return m_refer_posts.find( number ) != m_refer_posts.end(); } // 書き込みマークセット void NodeTreeBase::set_posted( const int number, const bool set ) { - if( ! m_vec_posted.size() ) m_vec_posted.resize( MAX_RESNUMBER ); - if( ! m_vec_refer_posted.size() ) m_vec_refer_posted.resize( MAX_RESNUMBER ); - - m_vec_posted[ number ] = set; + if( set ) { + m_posts.insert( number ); + } + else { + m_posts.erase( number ); + } // 自分の書き込みに対するレス - std::list< int > res_num = get_res_reference( number ); - std::list< int >::const_iterator it_res = res_num.begin(); + const std::list< int > res_num = get_res_reference( number ); // レスされたマークを設定する if( set ){ - for( ; it_res != res_num.end(); ++it_res ){ - const int n = ( *it_res ); - m_vec_refer_posted[ n ] = true; + for( const int n : res_num ) { + m_refer_posts.insert( n ); } } // レスされてなくなったので、マークを解除する else{ - for( ; it_res != res_num.end(); ++it_res ){ - const int n = ( *it_res ); + for( const int n : res_num ) { // レスアンカーのリストを取得 std::list< ANCINFO* > anchors = get_res_anchors( n ); @@ -3674,14 +3666,15 @@ void NodeTreeBase::set_posted( const int number, const bool set ) // 他の自分の書き込みに対するレスになっていないか? ANCINFO* anchor = ( *it_anchor ); + const auto end = m_posts.end(); for( int i = anchor->anc_from; i <= anchor->anc_to; i++ ){ // 他の自分の書き込みに対するレス - if( m_vec_posted[ i ] ) goto KEEP_POSTMARK; + if( m_posts.find( i ) != end ) goto KEEP_POSTMARK; } } // マークを解除する - m_vec_refer_posted[ n ] = false; + m_refer_posts.erase( n ); KEEP_POSTMARK:; } } @@ -3691,6 +3684,6 @@ KEEP_POSTMARK:; // 書き込み履歴のリセット void NodeTreeBase::clear_post_history() { - m_vec_posted.clear(); - m_vec_refer_posted.clear(); + m_posts.clear(); + m_refer_posts.clear(); } diff --git a/src/dbtree/nodetreebase.h b/src/dbtree/nodetreebase.h index 3d53a48f8..e3a160007 100644 --- a/src/dbtree/nodetreebase.h +++ b/src/dbtree/nodetreebase.h @@ -16,6 +16,7 @@ #include #include +#include namespace JDLIB { @@ -89,7 +90,7 @@ namespace DBTREE std::list< std::string > m_list_abone_word_global; // あぼーんする文字列(全体) std::list< std::string > m_list_abone_regex_global; // あぼーんする正規表現(全体) - std::vector< char > m_vec_abone_res; // レスあぼーん情報 + std::unordered_set< int > m_abone_reses; // レスあぼーん情報 bool m_abone_transparent; // 透明あぼーん bool m_abone_chain; // 連鎖あぼーん bool m_abone_age; // age ているレスはあぼーん @@ -97,10 +98,10 @@ namespace DBTREE bool m_abone_global; // 全体レベルでのあぼーんを有効にする // 自分が書き込んだレスか - std::vector< char > m_vec_posted; + std::unordered_set< int > m_posts; // 自分の書き込みにレスしているか - std::vector< char > m_vec_refer_posted; + std::unordered_set< int > m_refer_posts; // 未来のレスに対するアンカーがある時に使用する // check_reference() を参照 @@ -236,7 +237,7 @@ namespace DBTREE const std::list< std::string >& list_abone_name, const std::list< std::string >& list_abone_word, const std::list< std::string >& list_abone_regex, - const std::vector< char >& vec_abone_res, + const std::unordered_set< int >& abone_reses, const bool abone_transparent, const bool abone_chain, const bool abone_age, const bool abone_board, const bool abone_global ); @@ -245,8 +246,8 @@ namespace DBTREE void update_abone_all(); // 自分が書き込んだレスか - void copy_post_info( const std::vector< char >& vec_posted ){ m_vec_posted = vec_posted; } - const std::vector< char >& get_vec_posted(){ return m_vec_posted; } + void copy_post_info( const std::unordered_set< int >& posts ){ m_posts = posts; } + const std::unordered_set< int >& get_posts() const noexcept { return m_posts; } // 自分の書き込みにレスしたか bool is_refer_posted( const int number ); diff --git a/src/jdlib/constptr.h b/src/jdlib/constptr.h index 13f920c40..4bf145d02 100644 --- a/src/jdlib/constptr.h +++ b/src/jdlib/constptr.h @@ -19,9 +19,9 @@ namespace JDLIB T* operator -> () const noexcept { return m_p; } bool operator == ( const T *p ) const { return( m_p == p ); } bool operator != ( const T *p ) const { return( m_p != p ); } - bool operator ! () const { return ( m_p == NULL ); } + bool operator ! () const { return ( m_p == nullptr ); } T& operator * () const { return *m_p; } - operator bool () const { return ( m_p != NULL ); } + operator bool () const { return ( m_p != nullptr ); } T& operator [] ( const int i ){ return m_p[ i ]; } ConstPtr< T >& operator = ( const ConstPtr< T >& a ){ m_p = a.m_p; return *this; } @@ -29,7 +29,7 @@ namespace JDLIB ConstPtr< T >& operator = ( const T *p ){ m_p = p; return *this; } ConstPtr< T >& operator = ( T *p ){ m_p = p; return *this; } - void reset() { m_p = NULL; } + void reset() { m_p = nullptr; } // clear は deleteも実行 void clear(){