/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/ui/text.py

  • Committer: John Arbash Meinel
  • Date: 2010-08-05 16:27:35 UTC
  • mto: This revision was merged to the branch mainline in revision 5374.
  • Revision ID: john@arbash-meinel.com-20100805162735-172opvx34sr5gpbl
Find a case where we are wasting a bit of memory.

Specifically the 'build_details' tuple contains a lot of wasted references,
and we hold on to one of these for each record we are fetching.
And for something like 'bzr pack', that is all keys.

For just loading all text build details on my bzr+ repository, With:
locations = b.repository.texts._index.get_build_details(b.repository.texts.keys())
This drops the memory consumption from:
WorkingSize   77604KiB
 to
WorkingSize   64640KiB

Or around 10.6MB. I worked it out to a savings of about 80 bytes/record
on data that can have hundreds of thousands of records (in 32-bit).

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
 
38
38
""")
39
39
 
40
 
from bzrlib.osutils import watch_sigwinch
41
 
 
42
40
from bzrlib.ui import (
43
41
    UIFactory,
44
42
    NullProgressView,
62
60
        self.stderr = stderr
63
61
        # paints progress, network activity, etc
64
62
        self._progress_view = self.make_progress_view()
65
 
        # hook up the signals to watch for terminal size changes
66
 
        watch_sigwinch()
67
63
 
68
64
    def be_quiet(self, state):
69
65
        if state and not self._quiet:
157
153
        """Construct and return a new ProgressView subclass for this UI.
158
154
        """
159
155
        # with --quiet, never any progress view
160
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/320035>.  Otherwise if the
 
156
        # <https://bugs.launchpad.net/bzr/+bug/320035>.  Otherwise if the
161
157
        # user specifically requests either text or no progress bars, always
162
158
        # do that.  otherwise, guess based on $TERM and tty presence.
163
159
        if self.is_quiet():
233
229
 
234
230
    def show_warning(self, msg):
235
231
        self.clear_term()
 
232
        if isinstance(msg, unicode):
 
233
            te = osutils.get_terminal_encoding()
 
234
            msg = msg.encode(te, 'replace')
236
235
        self.stderr.write("bzr: warning: %s\n" % msg)
237
236
 
238
237
    def _progress_updated(self, task):
301
300
        # correspond reliably to overall command progress
302
301
        self.enable_bar = False
303
302
 
 
303
    def _avail_width(self):
 
304
        # we need one extra space for terminals that wrap on last char
 
305
        w = osutils.terminal_width() 
 
306
        if w is None:
 
307
            return w
 
308
        else:
 
309
            return w - 1
 
310
 
304
311
    def _show_line(self, s):
305
 
        # sys.stderr.write("progress %r\n" % s)
306
 
        width = osutils.terminal_width()
307
 
        if width is not None:
308
 
            # we need one extra space for terminals that wrap on last char
309
 
            width = width - 1
310
 
            s = '%-*.*s' % (width, width, s)
311
312
        self._term_file.write('\r' + s + '\r')
312
313
 
313
314
    def clear(self):
349
350
            return ''
350
351
 
351
352
    def _format_task(self, task):
 
353
        """Format task-specific parts of progress bar.
 
354
 
 
355
        :returns: (text_part, counter_part) both unicode strings.
 
356
        """
352
357
        if not task.show_count:
353
358
            s = ''
354
359
        elif task.current_cnt is not None and task.total_cnt is not None:
364
369
            t = t._parent_task
365
370
            if t.msg:
366
371
                m = t.msg + ':' + m
367
 
        return m + s
 
372
        return m, s
368
373
 
369
374
    def _render_line(self):
370
375
        bar_string = self._render_bar()
371
376
        if self._last_task:
372
 
            task_msg = self._format_task(self._last_task)
 
377
            task_part, counter_part = self._format_task(self._last_task)
373
378
        else:
374
 
            task_msg = ''
 
379
            task_part = counter_part = ''
375
380
        if self._last_task and not self._last_task.show_transport_activity:
376
381
            trans = ''
377
382
        else:
378
383
            trans = self._last_transport_msg
379
 
            if trans:
380
 
                trans += ' | '
381
 
        return (bar_string + trans + task_msg)
 
384
        # the bar separates the transport activity from the message, so even
 
385
        # if there's no bar or spinner, we must show something if both those
 
386
        # fields are present
 
387
        if (task_part or trans) and not bar_string:
 
388
            bar_string = '| '
 
389
        # preferentially truncate the task message if we don't have enough
 
390
        # space
 
391
        avail_width = self._avail_width()
 
392
        if avail_width is not None:
 
393
            # if terminal avail_width is unknown, don't truncate
 
394
            current_len = len(bar_string) + len(trans) + len(task_part) + len(counter_part)
 
395
            gap = current_len - avail_width
 
396
            if gap > 0:
 
397
                task_part = task_part[:-gap-2] + '..'
 
398
        s = trans + bar_string + task_part + counter_part
 
399
        if avail_width is not None:
 
400
            if len(s) < avail_width:
 
401
                s = s.ljust(avail_width)
 
402
            elif len(s) > avail_width:
 
403
                s = s[:avail_width]
 
404
        return s
382
405
 
383
406
    def _repaint(self):
384
407
        s = self._render_line()
440
463
            rate = (self._bytes_since_update
441
464
                    / (now - self._transport_update_time))
442
465
            # using base-10 units (see HACKING.txt).
443
 
            msg = ("%6dkB %5dkB/s" %
 
466
            msg = ("%6dkB %5dkB/s " %
444
467
                    (self._total_byte_count / 1000, int(rate) / 1000,))
445
468
            self._transport_update_time = now
446
469
            self._last_repaint = now