two patches

Tomaz Canabrava tcanabrava at kde.org
Fri Dec 12 11:03:54 PST 2014


> So I'm puzzled how often we are adding bookmark events and how that
> affects performance... or is this really just a first of a series and the
> others are more performance relevant?
>

First of a series.


>
> > diff --git a/dive.c b/dive.c
> > index b318c4b..4fb6717 100644
> > --- a/dive.c
> > +++ b/dive.c
> > @@ -150,6 +150,18 @@ void update_event_name(struct dive *d, struct event
> *event, char *name)
> >       free(remove);
> >  }
> >
> > +struct event *get_event_by_time(struct dive *d, uint32_t time){
> > +     if (!d)
> > +             return NULL;
> > +     struct divecomputer *dc = get_dive_dc(d, dc_number);
> > +     if (!dc)
> > +             return NULL;
> > +     struct event **events = &dc->events;
> > +     while((*events)->next && (*events)->time.seconds != time)
> > +             events = &(*events)->next;
> > +     return (*events);
> > +}
>
> Dear C expert... I am curious. Why are you doing this with a struct event
> **
> instead of just a struct event *... you need the ** if you want to be able
> to modify the list in an elegant way, but all you do here is walk the
> list, so this could drop one level of indirection... or am I missing
> something?
>

Copied from the code just above that one.


>
> > diff --git a/qt-ui/profile/diveeventitem.cpp
> b/qt-ui/profile/diveeventitem.cpp
> > index a9c3c3f..14cb0a3 100644
> > --- a/qt-ui/profile/diveeventitem.cpp
> > +++ b/qt-ui/profile/diveeventitem.cpp
> > @@ -9,6 +9,7 @@
> >  #include <QDebug>
> >  #include "gettextfromc.h"
> >  #include "metrics.h"
> > +#include <profile.h>
> >
> >  extern struct ev_select *ev_namelist;
> >  extern int evn_used;
> > @@ -152,18 +153,27 @@ bool DiveEventItem::shouldBeHidden()
> >
> >  void DiveEventItem::recalculatePos(bool instant)
> >  {
> > -     if (!vAxis || !hAxis || !internalEvent || !dataModel)
> > +     if (!vAxis || !hAxis || !internalEvent || !dataModel){
>
> WHITESPACE
>

MEEH


> >               return;
> > +     }
>
> And why add the curly braces, anyway?
>

I was debugging and forgot to remove them.


>
> > -     QModelIndexList result = dataModel->match(dataModel->index(0,
> DivePlotDataModel::TIME), Qt::DisplayRole, internalEvent->time.seconds);
> > -     if (result.isEmpty()) {
> > -             Q_ASSERT("can't find a spot in the dataModel");
> > -             hide();
> > -             return;
> > +     // find the correct time or interpolate between two points.
> > +     int depth = -1;
> > +     plot_data *entry = dataModel->data().entry;
> > +     for(int i = 0; i < dataModel->data().nr; i++){
> > +             if (entry[i].sec == internalEvent->time.seconds){
> > +                     depth = entry[i].depth;
> > +                     break;
> > +             } else if (entry[i].sec > internalEvent->time.seconds) {
> > +                     int min = entry[i-1].depth;
>
> This could do something really bad if for some reason
> internalEvent->time.seconds is negative, right? then entry[0].sec (which
> should always be 0) could already be bigger and we access element entry[-1]
>

Is that possible?


>
> > +                     int max = entry[i].depth;
> > +                     depth = min + ((max - min)/2);
> > +                     break;
> > +             }
> >       }
> > +
> >       if (!isVisible() && !shouldBeHidden())
> >               show();
> > -     int depth = dataModel->data(dataModel->index(result.first().row(),
> DivePlotDataModel::DEPTH)).toInt();
> >       qreal x = hAxis->posAtValue(internalEvent->time.seconds);
> >       qreal y = vAxis->posAtValue(depth);
> >       if (!instant)
> > @@ -172,4 +182,5 @@ void DiveEventItem::recalculatePos(bool instant)
> >               setPos(x, y);
> >       if (isVisible() && shouldBeHidden())
> >               hide();
> > +     qDebug() << pos();
>
> Grrrrrrrmbl
>

MEEEH


>
> > diff --git a/qt-ui/profile/profilewidget2.cpp
> b/qt-ui/profile/profilewidget2.cpp
> > index 1970561..1181fc5 100644
> > --- a/qt-ui/profile/profilewidget2.cpp
> > +++ b/qt-ui/profile/profilewidget2.cpp
> > @@ -1277,8 +1277,11 @@ void ProfileWidget2::removeEvent()
> >                                                                 tr("%1 @
> %2:%3").arg(event->name).arg(event->time.seconds /
> 60).arg(event->time.seconds % 60, 2, 10, QChar('0'))),
> >                                 QMessageBox::Ok | QMessageBox::Cancel)
> == QMessageBox::Ok) {
> >               remove_event(event);
> > +             copy_events(&current_dive->dc, &displayed_dive.dc);
>
> this leaks memory, the events in displayed_dive are overwritten without
> being freed. Call free_events() on the existing events in displayed_dive
>

Oh, sorry.


>
> >               mark_divelist_changed(true);
> > -             replot();
> > +             scene()->removeItem(item);
> > +             eventItems.removeOne(item);
> > +             item->deleteLater();
>
> You are the expert on that code :-)
>
> > @@ -1287,8 +1290,20 @@ void ProfileWidget2::addBookmark()
> >       QAction *action = qobject_cast<QAction *>(sender());
> >       QPointF scenePos =
> mapToScene(mapFromGlobal(action->data().toPoint()));
> >       add_event(current_dc, timeAxis->valueAt(scenePos),
> SAMPLE_EVENT_BOOKMARK, 0, 0, "bookmark");
> > +     copy_events(&current_dive->dc, &displayed_dive.dc);
>
> See above - leaks memory
>

Oh sorry2


>
> > +     struct event *ev = get_event_by_time(&displayed_dive,
> timeAxis->valueAt(scenePos));
> > +     qDebug() << "time = " << timeAxis->valueAt(scenePos) << "Event
> time: " << ev->time.seconds;
>
> Grrrrrmbl
>
> >       mark_divelist_changed(true);
> > -     replot();
> > +     DiveEventItem *item = new DiveEventItem();
> > +     item->setHorizontalAxis(timeAxis);
> > +     item->setVerticalAxis(profileYAxis);
> > +     item->setModel(dataModel);
> > +     item->setEvent(ev);
> > +     item->setZValue(2);
> > +     item->recalculatePos(true);
> > +     item->setVisible(true);
> > +     eventItems.push_back(item);
> > +     scene()->addItem(item);
> >  }
> >
> >  void ProfileWidget2::addSetpointChange()
> > @@ -1377,10 +1392,12 @@ void ProfileWidget2::editName()
> >               // order is important! first update the current dive (by
> matching the unchanged event),
> >               // then update the displayed dive (as event is part of the
> events on displayed dive
> >               // and will be freed as part of changing the name!
> > +             int time = event->time.seconds;
> >               update_event_name(current_dive, event,
> newName.toUtf8().data());
> >               update_event_name(&displayed_dive, event,
> newName.toUtf8().data());
> > +             struct event *ev = get_event_by_time(&displayed_dive,
> time);
> >               mark_divelist_changed(true);
> > -             replot();
> > +             item->setEvent(ev);
> >       }
> >  }
>
>
> So this is pretty invasive and the patch has a few issues.
>
> Why should this go in before 4.3? Is there a specific bug this addresses?
>

I was trying to find out why when moving a node for a few seconds while
adding a new dive used 100% of the CPU in release mode. turned out it was
because of too many replots that used the *very* expensive calls to
PainterPath.
while I was trying to fix that I got carried away. I think I'll just
generate the pixmap of the Glyphs and reuse them in the future for the
PainterPath issue.


> Just trying to understand the what and the why... if this should go in,
> can I get a cleaned up patch (I have taken the other one).
>
> /D
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.subsurface-divelog.org/pipermail/subsurface/attachments/20141212/55bb35ab/attachment.html>


More information about the subsurface mailing list