Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString

2014-02-21 Thread Oswald Buddenhagen
On Thu, Feb 20, 2014 at 12:07:44PM -0800, Thiago Macieira wrote:
 Em qui 20 fev 2014, às 19:56:42, Oswald Buddenhagen escreveu:
  what are you planning to do?
 
 This is the first step: remove setSharable so we have one fewer state to 
 check 
 during ref up  down. Keeping isSharedWith is no problem, as it doesn't 
 affect 
 the refcounting.
 
 The second step will be to use null d-pointers to indicate static data. That 
 means Q{String,ByteArray}Literal() and 
 Q{String,ByteArray,Vector}::fromRawData() don't have to have a d-pointer. For 
 the latter, it has the extra benefit that fromRawData() won't allocate memory 
 at all.
 
ah, you are thinking qt 6 here.

 Obviously, if the d-pointer is null, neither the pointer to the data nor the 
 size can be inside the d pointer. That means we have to extract the begin and 
 size from inside the d-pointer and move to the actual class.

another advantage of that model is that shared substrings would be
rather cheap, which means that my fromRawData() magic could be dropped,
and the existence of QStringRef could be re-evaluated (there is still
the refcount, but that may be insignificant in the bigger picture on
modern hardware).

 The third step will be to investigate whether Small String Optimisation makes 
 sense.

my guess is that it is not worth the effort.
in most cases where you are dealing with non-constant short strings you
are dealing with substrings with a very limited lifetime, which would be
well covered by the previous point.
and you have all the branches to deal with the denormalized strings
which make read-only operations slower.
anyway, have fun finding out. ;)
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString

2014-02-21 Thread Marc Mutz
On Thursday 20 February 2014 08:32:54 Thiago Macieira wrote:
 Please raise your hand if you knew we had that feature.

I'm sure you know that COW implementations that hand out references to shared 
state need the sharable flag[1]. So are we talking about removing the public 
part of the API?

Thanks,
Marc

[1] http://stackoverflow.com/questions/2526974/qt-undocumented-method-
setsharable/11108588#11108588

-- 
Marc Mutz marc.m...@kdab.com | Senior Software Engineer
KDAB (Deutschland) GmbH  Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString

2014-02-21 Thread Thiago Macieira
Em sex 21 fev 2014, às 16:49:39, Oswald Buddenhagen escreveu:
 ah, you are thinking qt 6 here.

Yes. I'd rather do the deprecation as soon as possible so we can have a 
smoother transition when we come to it.

  Obviously, if the d-pointer is null, neither the pointer to the data nor
  the  size can be inside the d pointer. That means we have to extract the
  begin and size from inside the d-pointer and move to the actual class.
 
 another advantage of that model is that shared substrings would be
 rather cheap, which means that my fromRawData() magic could be dropped,
 and the existence of QStringRef could be re-evaluated (there is still
 the refcount, but that may be insignificant in the bigger picture on
 modern hardware).

Indeed. And since QByteArrays will be cheap for constant data, one of the 
changes should be to remove the QByteArrayLiteral stuff that moc is carrying. 
For Qt 6, we can go back to a plain string table and only record the length.

That's another of the patches that I've been carrying for 2½ years.

But to do what you're asking, we have to revisit the problem of the 
terminating null. Any sub-string (except right()) will not have terminating 
nulls. That might become a big problem.

The other thing I'll need to investigate is the null-vs-empty distinction. 
Right now, they're distinct because we have a special value for the d pointer 
for a null object. If I remove the is static check on the refcount, I'll 
need to store the distinction somewhere. Options I can think of:

1) keep a non-null d for an empty-but-not null object (size == 0)
  a) d points to a read-write section of memory where we can ref up and down
drawback: slowness due to atomic operations in multiple cores

  b) d points to another special value, like d = 0x1
bool isStatic() const { return (quintptr(d)  ~1) == 0; }
/// Returns false if deallocation is necessary
bool deref() { return isStatic() || d-deref(); }

2) keep a null d for static empty, but a non null begin pointer
bool isNull() const { return d == nullptr  b == nullptr; }
bool isEmpty() const { return size == 0; }
T *constData() const { return b; }

drawback: constData() would return nullptr for a null object, which would 
allow people to start relying on that.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString

2014-02-21 Thread Thiago Macieira
Em sex 21 fev 2014, às 20:11:20, Marc Mutz escreveu:
 On Thursday 20 February 2014 08:32:54 Thiago Macieira wrote:
  Please raise your hand if you knew we had that feature.
 
 I'm sure you know that COW implementations that hand out references to
 shared state need the sharable flag[1]. So are we talking about removing
 the public part of the API?

Yes. I am talking about removing a method from accessible API (undocumented → 
private) in Qt 6.

As for creating a container pointing to non-permanent raw data, I think the 
solution of creating a deleter function makes more sense.

 [1] http://stackoverflow.com/questions/2526974/qt-undocumented-method- 
 setsharable/11108588#11108588

The URL says undocumented method.
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString

2014-02-20 Thread Thiago Macieira
Em qui 20 fev 2014, às 16:45:19, Tony Van Eerd escreveu:
  -Original Message-
  On Behalf Of Thiago Macieira
  Subject: [Development] RFC: Deprecating setSharable / isSharable in our
  containers and QString
  
  ... and removing them in Qt 6
  
  Please raise your hand if you knew we had that feature.
 
 They aren't even documented, are they? (ie
 http://qt-project.org/doc/qt-5.0/qtcore/qvector-members.html )
 
 And I couldn't find it on QString
 http://code.woboq.org/qt5/qtbase/src/corelib/tools/qstring.h.html

I'm guessing they're not.

 what about:
 
 detach()
 isDetached()
 isSharedWith()
 
 couldn't all these be noops and/or return true/false, etc, without
 breaking any code?  Isn't that the point of COW - you don't need to know?

I agree on detach(): you can easily trigger a detach() by calling data(). 
Well, as long as you ensure that your object is not const.

But we can't remove it because it's used by everything that does detaching. 
For example:

T *data() { detach(); return d-data(); }

The others are obscure indeed. As part of my efforts, I want to make QString / 
QByteArray / QVector keep a null d pointer for anything that doesn't require 
deallocation and reference counting -- that is, everything that is a static 
literal and the null / empty situations. If I do that, then:

QString hello = QStringLiteral(Hello);
QString world = QStringLiteral(World);

hello.d == world.d == nullptr;

So is hello.isSharedWith(world)? So I agree with you, we should also deprecate 
isSharedWith.

As for isDetached(), I have a use for it right now:

QByteArray QString::toLatin1_helper_inplace(QString s)
{
if (!s.isDetached())
return s.toLatin1();

// We can return our own buffer to the caller.
// Conversion to Latin-1 always shrinks the buffer by half.
const ushort *data = reinterpret_castconst ushort *(s.constData());
uint length = s.size();

// Swap the d pointers.
// Kids, avert your eyes. Don't try this at home.
[...]
}


-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString

2014-02-20 Thread Tony Van Eerd
 
 I agree on detach(): you can easily trigger a detach() by calling data().
 Well, as long as you ensure that your object is not const.
 

I wouldn't get rid of detach() just because data() can do the same thing.  If 
it is useful, I'd rather use the proper name for it.
The question is whether it is useful...

 But we can't remove it because it's used by everything that does detaching.
 For example:
 
   T *data() { detach(); return d-data(); }
 

... for *public* use.  It obvious it useful as a private function.

 
 As for isDetached(), I have a use for it right now:
 
 QByteArray QString::toLatin1_helper_inplace(QString s) {
 if (!s.isDetached())
 return s.toLatin1();
 
 // We can return our own buffer to the caller.
 // Conversion to Latin-1 always shrinks the buffer by half.
 const ushort *data = reinterpret_castconst ushort *(s.constData());
 uint length = s.size();
 
 // Swap the d pointers.
 // Kids, avert your eyes. Don't try this at home.
 [...]
 }
 

That's also private use.  So detach() and isDetached() could be private 
functions.

The (philosophical) question is If it is useful privately, might it also be 
useful publicly? If so, why keep the power away from clients?
(And there are various answers to each of those questions, in general.)

Tony

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString

2014-02-20 Thread Oswald Buddenhagen
On Thu, Feb 20, 2014 at 09:12:29AM -0800, Thiago Macieira wrote:
 The others are obscure indeed. As part of my efforts, I want to make QString 
 / 
 QByteArray / QVector keep a null d pointer for anything that doesn't require 
 deallocation and reference counting -- that is, everything that is a static 
 literal and the null / empty situations. If I do that, then:
 
   QString hello = QStringLiteral(Hello);
   QString world = QStringLiteral(World);
 
   hello.d == world.d == nullptr;
 
 So is hello.isSharedWith(world)? So I agree with you, we should also 
 deprecate 
 isSharedWith.
 
i introduced it for use in qmake/library/, to support an elaborate
fromRawData() optimization.
it wouldn't matter if it wouldn't return anything useful for constants.

what are you planning to do?
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] RFC: Deprecating setSharable / isSharable in our containers and QString

2014-02-20 Thread Thiago Macieira
Em qui 20 fev 2014, às 19:56:42, Oswald Buddenhagen escreveu:
 what are you planning to do?

This is the first step: remove setSharable so we have one fewer state to check 
during ref up  down. Keeping isSharedWith is no problem, as it doesn't affect 
the refcounting.

The second step will be to use null d-pointers to indicate static data. That 
means Q{String,ByteArray}Literal() and 
Q{String,ByteArray,Vector}::fromRawData() don't have to have a d-pointer. For 
the latter, it has the extra benefit that fromRawData() won't allocate memory 
at all.

Obviously, if the d-pointer is null, neither the pointer to the data nor the 
size can be inside the d pointer. That means we have to extract the begin and 
size from inside the d-pointer and move to the actual class. Fortunately, 
that's already implemented and very robust. I implemented it close to 3 years 
ago.
https://qt.gitorious.org/qt/thiago-intels-qtbase/commit/8ec07482b2ca9674ee72061c0273e527bc63ad47
https://qt.gitorious.org/qt/thiago-intels-qtbase/commit/3534934f0da0442a75b99fbab0328ce55c26798e

That means 
  sizeof(QString) == sizeof(QByteArray)== sizeof(QVector) == 3 * sizeof(void*)

I have a corresponding change to grow QVariant to 4 * sizeof(void*) so 
QStrings can fit.

The third step will be to investigate whether Small String Optimisation makes 
sense. By using the LSB in the d-pointer to indicate whether the SSO is 
active, we can store:

32-bit  64-bit
QString 5 chars 11 chars
QByteArray  11 chars23 chars
(including the ending null) 

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development