def add_lines(self, line_data: Mapping[str, Collection[TLineNo]]) -> None:
        """Add measured line data.

        `line_data` is a dictionary mapping file names to iterables of ints::

            { filename: { line1, line2, ... }, ...}

        """
        if self._debug.should("dataop"):
            self._debug.write("Adding lines: %d files, %d lines total" % (
                len(line_data), sum(len(lines) for lines in line_data.values()),
            ))
            if self._debug.should("dataop2"):
                for filename, linenos in sorted(line_data.items()):
                    self._debug.write(f"  {filename}: {linenos}")
        self._start_using()
        self._choose_lines_or_arcs(lines=True)
        if not line_data:
            return
        with self._connect() as con:
            self._set_context_id()
            for filename, linenos in line_data.items():
                line_bits = nums_to_numbits(linenos)
                file_id = self._file_id(filename, add=True)
                query = "select numbits from line_bits where file_id = ? and context_id = ?"
                with con.execute(query, (file_id, self._current_context_id)) as cur:
                    existing = list(cur)
                if existing:
                    line_bits = numbits_union(line_bits, existing[0][0])

                con.execute_void(
                    "insert or replace into line_bits " +
                    " (file_id, context_id, numbits) values (?, ?, ?)",
                    (file_id, self._current_context_id, line_bits),
                )
Add measured line data.

        `line_data` is a dictionary mapping file names to iterables of ints::

            { filename: { line1, line2, ... }, ...}

        
coverage/sqldata.py