Kaynağa Gözat

2009-02-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Extracted the algorithm to find the longest incremental sequence
	as max_sequence template.
	* src/LongestSequencePieceSelector.cc
	* src/a2algo.h
	* test/Makefile.am
	* test/a2algoTest.cc
Tatsuhiro Tsujikawa 16 yıl önce
ebeveyn
işleme
23a6eff88e
6 değiştirilmiş dosya ile 100 ekleme ve 28 silme
  1. 9 0
      ChangeLog
  2. 5 22
      src/LongestSequencePieceSelector.cc
  3. 34 0
      src/a2algo.h
  4. 2 1
      test/Makefile.am
  5. 6 5
      test/Makefile.in
  6. 44 0
      test/a2algoTest.cc

+ 9 - 0
ChangeLog

@@ -1,3 +1,12 @@
+2009-02-03  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Extracted the algorithm to find the longest incremental sequence
+	as max_sequence template.
+	* src/LongestSequencePieceSelector.cc
+	* src/a2algo.h
+	* test/Makefile.am
+	* test/a2algoTest.cc
+
 2009-02-03  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Removed TEXT_HTTP_SERVER_LISTEN_PORT from translation texts.

+ 5 - 22
src/LongestSequencePieceSelector.cc

@@ -33,6 +33,7 @@
  */
 /* copyright --> */
 #include "LongestSequencePieceSelector.h"
+#include "a2algo.h"
 
 namespace aria2 {
 
@@ -40,30 +41,12 @@ bool LongestSequencePieceSelector::select
 (size_t& index,
  const std::deque<size_t>& candidateIndexes) const
 {
-  size_t maxlen = 0;
-  size_t maxfirst = 0;
-  size_t i = 0;
-  size_t lenA = candidateIndexes.size();
-
-  while(i < lenA) {
-    size_t first = i;
-    size_t len = 1;
-    size_t prev = first;
-    ++i;
-    while(i < lenA && candidateIndexes[prev]+1 == candidateIndexes[i]) {
-      ++len;
-      prev = i;
-      ++i;
-    }
-    if(maxlen < len) {
-      maxlen = len;
-      maxfirst = first;
-    }
-  } 
-  if(maxlen == 0) {
+  std::pair<std::deque<size_t>::const_iterator, size_t> p = 
+    max_sequence(candidateIndexes.begin(), candidateIndexes.end());
+  if(p.second == 0) {
     return false;
   } else {
-    index = candidateIndexes[maxfirst+maxlen-1];
+    index = *(p.first)+p.second-1;
     return true;
   }
 }

+ 34 - 0
src/a2algo.h

@@ -50,6 +50,40 @@ OutputIterator ncopy(InputIterator first, InputIterator last,
   return x;
 }
 
+// Find the longest incremental sequence(such as 5,6,7,8,9) in the
+// range [first, last) and returns the pair of the iterator points the
+// first element of the sequence and the length of the sequence.  The
+// incremental sequence is such that value[i]+1 == value[j] for i,j
+// that satisfy i+1=j in a range.
+//
+// For example, the longest incremental sequence in {
+// 1,2,3,4,7,10,11,12,13,14,15,100,112,113,114} is
+// {10,11,12,13,14,15}.  Therefore, returns the iterator points to 10
+// and the length 6.
+template<typename InputIterator>
+std::pair<InputIterator, size_t> max_sequence(InputIterator first,
+					      InputIterator last)
+{
+  InputIterator maxfirst = last;
+  size_t maxlen = 0;
+  while(first != last) {
+    InputIterator seqfirst = first;
+    size_t len = 1;
+    InputIterator prev = seqfirst;
+    ++first;
+    while(first != last && *prev+1 == *first) {
+      ++len;
+      prev = first;
+      ++first;
+    }
+    if(maxlen < len) {
+      maxlen = len;
+      maxfirst = seqfirst;
+    }
+  }
+  return std::pair<InputIterator, size_t>(maxfirst, maxlen);
+}
+
 } // namespace aria2
 
 #endif // _D_A2_ALGO_H_

+ 2 - 1
test/Makefile.am

@@ -67,7 +67,8 @@ aria2c_SOURCES = AllTest.cc\
 	BencodeTest.cc\
 	SequentialPickerTest.cc\
 	RarestPieceSelectorTest.cc\
-	LongestSequencePieceSelectorTest.cc
+	LongestSequencePieceSelectorTest.cc\
+	a2algoTest.cc
 
 if HAVE_LIBZ
 aria2c_SOURCES += GZipDecoderTest.cc

+ 6 - 5
test/Makefile.in

@@ -193,7 +193,7 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
 	OptionParserTest.cc SimpleDNSCacheTest.cc \
 	DownloadHelperTest.cc BencodeTest.cc SequentialPickerTest.cc \
 	RarestPieceSelectorTest.cc LongestSequencePieceSelectorTest.cc \
-	GZipDecoderTest.cc Sqlite3MozCookieParserTest.cc \
+	a2algoTest.cc GZipDecoderTest.cc Sqlite3MozCookieParserTest.cc \
 	MessageDigestHelperTest.cc \
 	IteratableChunkChecksumValidatorTest.cc \
 	IteratableChecksumValidatorTest.cc BtAllowedFastMessageTest.cc \
@@ -362,9 +362,9 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
 	SimpleDNSCacheTest.$(OBJEXT) DownloadHelperTest.$(OBJEXT) \
 	BencodeTest.$(OBJEXT) SequentialPickerTest.$(OBJEXT) \
 	RarestPieceSelectorTest.$(OBJEXT) \
-	LongestSequencePieceSelectorTest.$(OBJEXT) $(am__objects_1) \
-	$(am__objects_2) $(am__objects_3) $(am__objects_4) \
-	$(am__objects_5)
+	LongestSequencePieceSelectorTest.$(OBJEXT) \
+	a2algoTest.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
+	$(am__objects_3) $(am__objects_4) $(am__objects_5)
 aria2c_OBJECTS = $(am_aria2c_OBJECTS)
 am__DEPENDENCIES_1 =
 aria2c_DEPENDENCIES = ../src/libaria2c.a ../src/download_helper.o \
@@ -589,7 +589,7 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
 	OptionParserTest.cc SimpleDNSCacheTest.cc \
 	DownloadHelperTest.cc BencodeTest.cc SequentialPickerTest.cc \
 	RarestPieceSelectorTest.cc LongestSequencePieceSelectorTest.cc \
-	$(am__append_1) $(am__append_2) $(am__append_3) \
+	a2algoTest.cc $(am__append_1) $(am__append_2) $(am__append_3) \
 	$(am__append_4) $(am__append_5)
 
 #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
@@ -823,6 +823,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UriListParserTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XORCloserTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a2algoTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a2functionalTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array_funTest.Po@am__quote@
 

+ 44 - 0
test/a2algoTest.cc

@@ -0,0 +1,44 @@
+#include "a2algo.h"
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "array_fun.h"
+
+namespace aria2 {
+
+class a2algoTest:public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE(a2algoTest);
+  CPPUNIT_TEST(testSelect);
+  CPPUNIT_TEST_SUITE_END();
+public:
+  void setUp() {}
+
+  void tearDown() {}
+
+  void testSelect();
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION(a2algoTest);
+
+void a2algoTest::testSelect()
+{
+  size_t A[] = { 1,2,3,4,7,10,11,12,13,14,15,100,112,113,114 };
+
+  std::pair<size_t*, size_t> p = max_sequence(&A[0], &A[arrayLength(A)]);
+  CPPUNIT_ASSERT_EQUAL(&A[5], p.first);
+  CPPUNIT_ASSERT_EQUAL((size_t)6, p.second);
+
+
+  p = max_sequence(&A[0], &A[0]);
+  CPPUNIT_ASSERT_EQUAL(&A[0], p.first);
+  CPPUNIT_ASSERT_EQUAL((size_t)0, p.second);
+
+
+  p = max_sequence(&A[0], &A[4]);
+  CPPUNIT_ASSERT_EQUAL(&A[0], p.first);
+  CPPUNIT_ASSERT_EQUAL((size_t)4, p.second);
+}
+
+} // namespace aria2