leveldb: DB.tableRangeCompaction: retry 'all level' compaction until nothing to compact; and don't limit single level compaction
diff --git a/leveldb/db_compaction.go b/leveldb/db_compaction.go
index 333ea9b..8b8dc4a 100644
--- a/leveldb/db_compaction.go
+++ b/leveldb/db_compaction.go
@@ -574,23 +574,33 @@
 
 	db.logf("table@compaction range L%d %q:%q", level, umin, umax)
 	if level >= 0 {
-		if c := db.s.getCompactionRange(level, umin, umax); c != nil {
+		if c := db.s.getCompactionRange(level, umin, umax, true); c != nil {
 			db.tableCompaction(c, true)
 		}
 	} else {
-		// Scan for maximum level with overlapped tables.
-		v := db.s.version()
-		m := 1
-		for i, t := range v.tables[1:] {
-			if t.overlaps(db.s.icmp, umin, umax, false) {
-				m = i + 1
-			}
-		}
-		v.release()
+		// Retry until nothing to compact.
+		for {
+			compacted := false
 
-		for level := 0; level < m; level++ {
-			if c := db.s.getCompactionRange(level, umin, umax); c != nil {
-				db.tableCompaction(c, true)
+			// Scan for maximum level with overlapped tables.
+			v := db.s.version()
+			m := 1
+			for i, t := range v.tables[1:] {
+				if t.overlaps(db.s.icmp, umin, umax, false) {
+					m = i + 1
+				}
+			}
+			v.release()
+
+			for level := 0; level < m; level++ {
+				if c := db.s.getCompactionRange(level, umin, umax, false); c != nil {
+					db.tableCompaction(c, true)
+					compacted = true
+				}
+			}
+
+			if !compacted {
+				break
 			}
 		}
 	}
diff --git a/leveldb/session_compaction.go b/leveldb/session_compaction.go
index 7c5a794..36aa1d8 100644
--- a/leveldb/session_compaction.go
+++ b/leveldb/session_compaction.go
@@ -73,7 +73,7 @@
 }
 
 // Create compaction from given level and range; need external synchronization.
-func (s *session) getCompactionRange(level int, umin, umax []byte) *compaction {
+func (s *session) getCompactionRange(level int, umin, umax []byte, noLimit bool) *compaction {
 	v := s.version()
 
 	t0 := v.tables[level].getOverlaps(nil, s.icmp, umin, umax, level == 0)
@@ -86,7 +86,7 @@
 	// But we cannot do this for level-0 since level-0 files can overlap
 	// and we must not pick one file and drop another older file if the
 	// two files overlap.
-	if level > 0 {
+	if !noLimit && level > 0 {
 		limit := uint64(v.s.o.GetCompactionSourceLimit(level))
 		total := uint64(0)
 		for i, t := range t0 {