public Compaction PickCompaction() {
		Compaction c;
		int level;

		// We prefer compactions triggered by too much data in a level over
		// the compactions triggered by seeks.
		boolean size_compaction = (current_.compaction_score_ >= 1);
		boolean seek_compaction = (current_.file_to_compact_ != null);
		if (size_compaction) {
			level = current_.compaction_level_;
			assert (level >= 0);
			assert (level + 1 < config.kNumLevels);
			c = new Compaction(level);

			// Pick the first file that comes after compact_pointer_[level]
			for (int i = 0; i < current_.files_.get(level).size(); i++) {
				FileMetaData f = current_.files_.get(level).get(i);
				if (compact_pointer_[level] == ""
						|| icmp_.Compare(f.largest.Encode(), new Slice(
								compact_pointer_[level])) > 0) {
					c.inputs_.get(0).add(f);
					break;
				}
			}
			if (c.inputs_.get(0).isEmpty()) {
				// Wrap-around to the beginning of the key space
				c.inputs_.get(0).add(current_.files_.get(level).get(0));
			}
		} else if (seek_compaction) {
			level = current_.file_to_compact_level_;
			c = new Compaction(level);
			c.inputs_.get(0).add(current_.file_to_compact_);
		} else {
			return null;
		}

		c.input_version_ = current_;
		c.input_version_.Ref();

		// Files in level 0 may overlap each other, so pick up all overlapping
		// ones
		if (level == 0) {
			InternalKey smallest = new InternalKey();
			InternalKey largest = new InternalKey();
			GetRange(c.inputs_.get(0), smallest, largest);
			// Note that the next call will discard the file we placed in
			// c->inputs_[0] earlier and replace it with an overlapping set
			// which will include the picked file.
			current_.GetOverlappingInputs(0, smallest, largest,
					c.inputs_.get(0));
			assert (!c.inputs_.get(0).isEmpty());
		}

		// set files for "level + 1"
		SetupOtherInputs(c);

		return c;
	}