From c846b8ba4e99d71711a1a87e02fbf986dd25fd39 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 4 Sep 2020 09:02:18 +0000 Subject: [PATCH] fixed the wrong positioner invocation bug in BinaryHeap::remove() --- qse/include/qse/cmn/Array.hpp | 20 ++--- qse/include/qse/cmn/BinaryHeap.hpp | 10 ++- qse/include/qse/cmn/time.h | 4 + qse/samples/cmn/Makefile.am | 4 +- qse/samples/cmn/Makefile.in | 75 +++++++++++------- qse/samples/cmn/bh03.cpp | 122 +++++++++++++++++++++++++++++ 6 files changed, 190 insertions(+), 45 deletions(-) create mode 100644 qse/samples/cmn/bh03.cpp diff --git a/qse/include/qse/cmn/Array.hpp b/qse/include/qse/cmn/Array.hpp index 48b22e96..9c389c00 100644 --- a/qse/include/qse/cmn/Array.hpp +++ b/qse/include/qse/cmn/Array.hpp @@ -547,18 +547,18 @@ public: qse_size_t upsert (qse_size_t index, const T& value) { if (index < this->count) - return this->update (index, value); + return this->update(index, value); else - return this->insert (index, value); + return this->insert(index, value); } #if defined(QSE_CPP_ENABLE_CPP11_MOVE) qse_size_t upsert (qse_size_t index, T&& value) { if (index < this->count) - return this->update (index, QSE_CPP_RVREF(value)); + return this->update(index, QSE_CPP_RVREF(value)); else - return this->insert (index, QSE_CPP_RVREF(value)); + return this->insert(index, QSE_CPP_RVREF(value)); } #endif @@ -567,7 +567,7 @@ public: if (index < this->count) return index; // no update else - return this->insert (index, value); + return this->insert(index, value); } #if defined(QSE_CPP_ENABLE_CPP11_MOVE) @@ -576,31 +576,31 @@ public: if (index < this->count) return index; // no update else - return this->insert (index, QSE_CPP_RVREF(value)); + return this->insert(index, QSE_CPP_RVREF(value)); } #endif qse_size_t insertFirst (const T& value) { - return this->insert (0, value); + return this->insert(0, value); } #if defined(QSE_CPP_ENABLE_CPP11_MOVE) qse_size_t insertFirst (T&& value) { - return this->insert (0, QSE_CPP_RVREF(value)); + return this->insert(0, QSE_CPP_RVREF(value)); } #endif qse_size_t insertLast (const T& value) { - return this->insert (this->getSize(), value); + return this->insert(this->getSize(), value); } #if defined(QSE_CPP_ENABLE_CPP11_MOVE) qse_size_t insertLast (T&& value) { - return this->insert (this->getSize(), QSE_CPP_RVREF(value)); + return this->insert(this->getSize(), QSE_CPP_RVREF(value)); } #endif diff --git a/qse/include/qse/cmn/BinaryHeap.hpp b/qse/include/qse/cmn/BinaryHeap.hpp index 4ff509da..08e622b6 100644 --- a/qse/include/qse/cmn/BinaryHeap.hpp +++ b/qse/include/qse/cmn/BinaryHeap.hpp @@ -240,7 +240,6 @@ public: if (this->count == 1) { - QSE_ASSERT (index == 0); ParentType::remove (this->count - 1); } else if (this->count > 1) @@ -251,11 +250,14 @@ public: // copy the last item to the position to remove ParentType::update (index, QSE_CPP_RVREF(this->buffer[this->count - 1])); - // delete the last item - ParentType::remove (this->count - 1); + // decrement the count as if the last item has been deleted. + this->count = this->count - 1; // relocate the item - (this->greater_than (this->buffer[index], old))? this->sift_up(index): this->sift_down(index); + (this->greater_than(this->buffer[index], old))? this->sift_up(index): this->sift_down(index); + + // call the positioner on the actual item removed + this->_positioner (old, INVALID_INDEX); } } diff --git a/qse/include/qse/cmn/time.h b/qse/include/qse/cmn/time.h index b747462a..6432c4ea 100644 --- a/qse/include/qse/cmn/time.h +++ b/qse/include/qse/cmn/time.h @@ -93,7 +93,11 @@ #define QSE_SEC_TO_USEC(sec) ((sec) * QSE_USECS_PER_SEC) #define QSE_USEC_TO_SEC(usec) ((usec) / QSE_USECS_PER_SEC) +#if defined(QSE_SIZEOF_INT64_T) && (QSE_SIZEOF_INT64_T > 0) typedef qse_int64_t qse_ntime_sec_t; +#else +typedef qse_int32_t qse_ntime_sec_t; +#endif typedef qse_int32_t qse_ntime_nsec_t; /** diff --git a/qse/samples/cmn/Makefile.am b/qse/samples/cmn/Makefile.am index 62165035..706c14ca 100644 --- a/qse/samples/cmn/Makefile.am +++ b/qse/samples/cmn/Makefile.am @@ -74,7 +74,7 @@ if ENABLE_CXX #rex02_CXXFLAGS = -I/usr/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread #rex02_LDFLAGS = -pthread -Wl,-Bsymbolic-functions -lwx_gtk2ud_richtext-2.8 -lwx_gtk2ud_aui-2.8 -lwx_gtk2ud_xrc-2.8 -lwx_gtk2ud_qa-2.8 -lwx_gtk2ud_html-2.8 -lwx_gtk2ud_adv-2.8 -lwx_gtk2ud_core-2.8 -lwx_baseud_xml-2.8 -lwx_baseud_net-2.8 -lwx_baseud-2.8 -bin_PROGRAMS += arr02 arr03 bh01 bh02 hl01 htb02 rbt02 rbt03 sp01 sp02 str02 +bin_PROGRAMS += arr02 arr03 bh01 bh02 bh03 hl01 htb02 rbt02 rbt03 sp01 sp02 str02 arr02_SOURCES = arr02.cpp @@ -84,6 +84,8 @@ bh01_SOURCES = bh01.cpp bh02_SOURCES = bh02.cpp +bh03_SOURCES = bh03.cpp + hl01_SOURCES = hl01.cpp htb02_SOURCES = htb02.cpp diff --git a/qse/samples/cmn/Makefile.in b/qse/samples/cmn/Makefile.in index d459ad76..0f212ac3 100644 --- a/qse/samples/cmn/Makefile.in +++ b/qse/samples/cmn/Makefile.in @@ -102,7 +102,7 @@ bin_PROGRAMS = arr01$(EXEEXT) chr01$(EXEEXT) dll$(EXEEXT) \ #rex02_SOURCES = rex02.cpp #rex02_CXXFLAGS = -I/usr/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread #rex02_LDFLAGS = -pthread -Wl,-Bsymbolic-functions -lwx_gtk2ud_richtext-2.8 -lwx_gtk2ud_aui-2.8 -lwx_gtk2ud_xrc-2.8 -lwx_gtk2ud_qa-2.8 -lwx_gtk2ud_html-2.8 -lwx_gtk2ud_adv-2.8 -lwx_gtk2ud_core-2.8 -lwx_baseud_xml-2.8 -lwx_baseud_net-2.8 -lwx_baseud-2.8 -@ENABLE_CXX_TRUE@am__append_2 = arr02 arr03 bh01 bh02 hl01 htb02 rbt02 rbt03 sp01 sp02 str02 +@ENABLE_CXX_TRUE@am__append_2 = arr02 arr03 bh01 bh02 bh03 hl01 htb02 rbt02 rbt03 sp01 sp02 str02 subdir = samples/cmn ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \ @@ -122,9 +122,10 @@ CONFIG_HEADER = $(top_builddir)/include/qse/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @ENABLE_CXX_TRUE@am__EXEEXT_1 = arr02$(EXEEXT) arr03$(EXEEXT) \ -@ENABLE_CXX_TRUE@ bh01$(EXEEXT) bh02$(EXEEXT) hl01$(EXEEXT) \ -@ENABLE_CXX_TRUE@ htb02$(EXEEXT) rbt02$(EXEEXT) rbt03$(EXEEXT) \ -@ENABLE_CXX_TRUE@ sp01$(EXEEXT) sp02$(EXEEXT) str02$(EXEEXT) +@ENABLE_CXX_TRUE@ bh01$(EXEEXT) bh02$(EXEEXT) bh03$(EXEEXT) \ +@ENABLE_CXX_TRUE@ hl01$(EXEEXT) htb02$(EXEEXT) rbt02$(EXEEXT) \ +@ENABLE_CXX_TRUE@ rbt03$(EXEEXT) sp01$(EXEEXT) sp02$(EXEEXT) \ +@ENABLE_CXX_TRUE@ str02$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_arr01_OBJECTS = arr01.$(OBJEXT) @@ -157,6 +158,11 @@ am__bh02_SOURCES_DIST = bh02.cpp bh02_OBJECTS = $(am_bh02_OBJECTS) bh02_LDADD = $(LDADD) bh02_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +am__bh03_SOURCES_DIST = bh03.cpp +@ENABLE_CXX_TRUE@am_bh03_OBJECTS = bh03.$(OBJEXT) +bh03_OBJECTS = $(am_bh03_OBJECTS) +bh03_LDADD = $(LDADD) +bh03_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) am_chr01_OBJECTS = chr01.$(OBJEXT) chr01_OBJECTS = $(am_chr01_OBJECTS) chr01_LDADD = $(LDADD) @@ -309,18 +315,18 @@ depcomp = $(SHELL) $(top_srcdir)/ac/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/arr01.Po ./$(DEPDIR)/arr02.Po \ ./$(DEPDIR)/arr03.Po ./$(DEPDIR)/bh01.Po ./$(DEPDIR)/bh02.Po \ - ./$(DEPDIR)/chr01.Po ./$(DEPDIR)/dll.Po ./$(DEPDIR)/env01.Po \ - ./$(DEPDIR)/fma.Po ./$(DEPDIR)/fmt01.Po ./$(DEPDIR)/fmt02.Po \ - ./$(DEPDIR)/hl01.Po ./$(DEPDIR)/htb01.Po ./$(DEPDIR)/htb02.Po \ - ./$(DEPDIR)/htl01.Po ./$(DEPDIR)/ipad01.Po \ - ./$(DEPDIR)/main01.Po ./$(DEPDIR)/main02.Po \ - ./$(DEPDIR)/mbwc01.Po ./$(DEPDIR)/mbwc02.Po ./$(DEPDIR)/oht.Po \ - ./$(DEPDIR)/path01.Po ./$(DEPDIR)/pma.Po ./$(DEPDIR)/rbt01.Po \ - ./$(DEPDIR)/rbt02.Po ./$(DEPDIR)/rbt03.Po ./$(DEPDIR)/rex01.Po \ - ./$(DEPDIR)/sll.Po ./$(DEPDIR)/slmb01.Po ./$(DEPDIR)/sp01.Po \ - ./$(DEPDIR)/sp02.Po ./$(DEPDIR)/str01.Po ./$(DEPDIR)/str02.Po \ - ./$(DEPDIR)/time.Po ./$(DEPDIR)/tre01.Po ./$(DEPDIR)/uri01.Po \ - ./$(DEPDIR)/xma.Po + ./$(DEPDIR)/bh03.Po ./$(DEPDIR)/chr01.Po ./$(DEPDIR)/dll.Po \ + ./$(DEPDIR)/env01.Po ./$(DEPDIR)/fma.Po ./$(DEPDIR)/fmt01.Po \ + ./$(DEPDIR)/fmt02.Po ./$(DEPDIR)/hl01.Po ./$(DEPDIR)/htb01.Po \ + ./$(DEPDIR)/htb02.Po ./$(DEPDIR)/htl01.Po \ + ./$(DEPDIR)/ipad01.Po ./$(DEPDIR)/main01.Po \ + ./$(DEPDIR)/main02.Po ./$(DEPDIR)/mbwc01.Po \ + ./$(DEPDIR)/mbwc02.Po ./$(DEPDIR)/oht.Po ./$(DEPDIR)/path01.Po \ + ./$(DEPDIR)/pma.Po ./$(DEPDIR)/rbt01.Po ./$(DEPDIR)/rbt02.Po \ + ./$(DEPDIR)/rbt03.Po ./$(DEPDIR)/rex01.Po ./$(DEPDIR)/sll.Po \ + ./$(DEPDIR)/slmb01.Po ./$(DEPDIR)/sp01.Po ./$(DEPDIR)/sp02.Po \ + ./$(DEPDIR)/str01.Po ./$(DEPDIR)/str02.Po ./$(DEPDIR)/time.Po \ + ./$(DEPDIR)/tre01.Po ./$(DEPDIR)/uri01.Po ./$(DEPDIR)/xma.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -359,22 +365,23 @@ am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(arr01_SOURCES) $(arr02_SOURCES) $(arr03_SOURCES) \ - $(bh01_SOURCES) $(bh02_SOURCES) $(chr01_SOURCES) \ - $(dll_SOURCES) $(env01_SOURCES) $(fma_SOURCES) \ - $(fmt01_SOURCES) $(fmt02_SOURCES) $(hl01_SOURCES) \ - $(htb01_SOURCES) $(htb02_SOURCES) htl01.c $(ipad01_SOURCES) \ - $(main01_SOURCES) $(main02_SOURCES) $(mbwc01_SOURCES) \ - $(mbwc02_SOURCES) $(oht_SOURCES) $(path01_SOURCES) \ - $(pma_SOURCES) $(rbt01_SOURCES) $(rbt02_SOURCES) \ - $(rbt03_SOURCES) $(rex01_SOURCES) $(sll_SOURCES) \ - $(slmb01_SOURCES) $(sp01_SOURCES) $(sp02_SOURCES) \ - $(str01_SOURCES) $(str02_SOURCES) $(time_SOURCES) \ - $(tre01_SOURCES) uri01.c $(xma_SOURCES) + $(bh01_SOURCES) $(bh02_SOURCES) $(bh03_SOURCES) \ + $(chr01_SOURCES) $(dll_SOURCES) $(env01_SOURCES) \ + $(fma_SOURCES) $(fmt01_SOURCES) $(fmt02_SOURCES) \ + $(hl01_SOURCES) $(htb01_SOURCES) $(htb02_SOURCES) htl01.c \ + $(ipad01_SOURCES) $(main01_SOURCES) $(main02_SOURCES) \ + $(mbwc01_SOURCES) $(mbwc02_SOURCES) $(oht_SOURCES) \ + $(path01_SOURCES) $(pma_SOURCES) $(rbt01_SOURCES) \ + $(rbt02_SOURCES) $(rbt03_SOURCES) $(rex01_SOURCES) \ + $(sll_SOURCES) $(slmb01_SOURCES) $(sp01_SOURCES) \ + $(sp02_SOURCES) $(str01_SOURCES) $(str02_SOURCES) \ + $(time_SOURCES) $(tre01_SOURCES) uri01.c $(xma_SOURCES) DIST_SOURCES = $(arr01_SOURCES) $(am__arr02_SOURCES_DIST) \ $(am__arr03_SOURCES_DIST) $(am__bh01_SOURCES_DIST) \ - $(am__bh02_SOURCES_DIST) $(chr01_SOURCES) $(dll_SOURCES) \ - $(env01_SOURCES) $(fma_SOURCES) $(fmt01_SOURCES) \ - $(fmt02_SOURCES) $(am__hl01_SOURCES_DIST) $(htb01_SOURCES) \ + $(am__bh02_SOURCES_DIST) $(am__bh03_SOURCES_DIST) \ + $(chr01_SOURCES) $(dll_SOURCES) $(env01_SOURCES) \ + $(fma_SOURCES) $(fmt01_SOURCES) $(fmt02_SOURCES) \ + $(am__hl01_SOURCES_DIST) $(htb01_SOURCES) \ $(am__htb02_SOURCES_DIST) htl01.c $(ipad01_SOURCES) \ $(main01_SOURCES) $(main02_SOURCES) $(mbwc01_SOURCES) \ $(mbwc02_SOURCES) $(oht_SOURCES) $(path01_SOURCES) \ @@ -600,6 +607,7 @@ xma_SOURCES = xma.c @ENABLE_CXX_TRUE@arr03_SOURCES = arr03.cpp @ENABLE_CXX_TRUE@bh01_SOURCES = bh01.cpp @ENABLE_CXX_TRUE@bh02_SOURCES = bh02.cpp +@ENABLE_CXX_TRUE@bh03_SOURCES = bh03.cpp @ENABLE_CXX_TRUE@hl01_SOURCES = hl01.cpp @ENABLE_CXX_TRUE@htb02_SOURCES = htb02.cpp @ENABLE_CXX_TRUE@rbt02_SOURCES = rbt02.cpp #RedBlackTree @@ -710,6 +718,10 @@ bh02$(EXEEXT): $(bh02_OBJECTS) $(bh02_DEPENDENCIES) $(EXTRA_bh02_DEPENDENCIES) @rm -f bh02$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(bh02_OBJECTS) $(bh02_LDADD) $(LIBS) +bh03$(EXEEXT): $(bh03_OBJECTS) $(bh03_DEPENDENCIES) $(EXTRA_bh03_DEPENDENCIES) + @rm -f bh03$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(bh03_OBJECTS) $(bh03_LDADD) $(LIBS) + chr01$(EXEEXT): $(chr01_OBJECTS) $(chr01_DEPENDENCIES) $(EXTRA_chr01_DEPENDENCIES) @rm -f chr01$(EXEEXT) $(AM_V_CCLD)$(LINK) $(chr01_OBJECTS) $(chr01_LDADD) $(LIBS) @@ -849,6 +861,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arr03.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bh01.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bh02.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bh03.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr01.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dll.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env01.Po@am__quote@ # am--include-marker @@ -1068,6 +1081,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/arr03.Po -rm -f ./$(DEPDIR)/bh01.Po -rm -f ./$(DEPDIR)/bh02.Po + -rm -f ./$(DEPDIR)/bh03.Po -rm -f ./$(DEPDIR)/chr01.Po -rm -f ./$(DEPDIR)/dll.Po -rm -f ./$(DEPDIR)/env01.Po @@ -1150,6 +1164,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/arr03.Po -rm -f ./$(DEPDIR)/bh01.Po -rm -f ./$(DEPDIR)/bh02.Po + -rm -f ./$(DEPDIR)/bh03.Po -rm -f ./$(DEPDIR)/chr01.Po -rm -f ./$(DEPDIR)/dll.Po -rm -f ./$(DEPDIR)/env01.Po diff --git a/qse/samples/cmn/bh03.cpp b/qse/samples/cmn/bh03.cpp new file mode 100644 index 00000000..d764fde6 --- /dev/null +++ b/qse/samples/cmn/bh03.cpp @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include +#include +#include + + +//#define MAX_HEAP + +class Julia +{ +public: + struct julia_t + { + julia_t(int v): v(v), heap_pos(~(qse_size_t)0) {} + + int v; + qse_size_t heap_pos; + }; + + Julia (int q = 0): x(QSE_NULL) + { + this->x = new julia_t (q); + } + + Julia (const Julia& q): x(QSE_NULL) + { + this->x = new julia_t (*q.x); + } + +#if defined(QSE_CPP_ENABLE_CPP11_MOVE) + Julia (Julia&& q) + { + this->x = q.x; + q.x = QSE_NULL; + } +#endif + + ~Julia() + { + if (this->x) delete this->x; + } + + Julia& operator= (const Julia& q) + { + if (this != &q) + { + if (this->x) { delete this->x; this->x = QSE_NULL; } + this->x = new julia_t (*q.x); + } + + return *this; + } + +#if defined(QSE_CPP_ENABLE_CPP11_MOVE) + Julia& operator= (Julia&& q) + { + if (this != &q) + { + if (this->x) { delete this->x; this->x = QSE_NULL; } + this->x = q.x; + q.x = QSE_NULL; + } + + return *this; + } +#endif + +#if defined(MAX_HEAP) + bool operator> (const Julia& q) const { return this->x->v > q.x->v; } +#else + bool operator> (const Julia& q) const { return this->x->v < q.x->v; } +#endif + julia_t* x; +}; + +struct JuliaGreaterThan +{ + bool operator() (const Julia& b1, const Julia& b2) const + { + return b1 > b2; + } +}; + +struct JuliaOnAssign +{ + void operator() (Julia& b, qse_size_t index) const + { + b.x->heap_pos = index; + //printf ("%p[%d] to position %zd\n", &b, b.x->v, index); + } +}; + +typedef QSE::BinaryHeap JuliaHeap; + +int main () +{ + { + JuliaHeap jh; + jh.insert (Julia(10)); + jh.insert (Julia(20)); + jh.insert (Julia(30)); + jh.insert (Julia(40)); + jh.insert (Julia(50)); + jh.remove (1); + + // test if the positioner(JuliaOnAssign) is called properly. + QSE_ASSERT (jh.getValueAt(0).x->heap_pos == 0); + QSE_ASSERT (jh.getValueAt(1).x->heap_pos == 1); + QSE_ASSERT (jh.getValueAt(2).x->heap_pos == 2); + QSE_ASSERT (jh.getValueAt(3).x->heap_pos == 3); + + printf ("%zd\n", jh.getValueAt(0).x->heap_pos); + printf ("%zd\n", jh.getValueAt(1).x->heap_pos); + printf ("%zd\n", jh.getValueAt(2).x->heap_pos); + printf ("%zd\n", jh.getValueAt(3).x->heap_pos); + } + + return 0; +}