From api-return-40-apmail-directory-api-archive=directory.apache.org@directory.apache.org Wed Jan 13 23:44:07 2010
Return-Path:
Delivered-To: apmail-directory-api-archive@minotaur.apache.org
Received: (qmail 37200 invoked from network); 13 Jan 2010 23:44:07 -0000
Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3)
by minotaur.apache.org with SMTP; 13 Jan 2010 23:44:07 -0000
Received: (qmail 31236 invoked by uid 500); 13 Jan 2010 23:44:07 -0000
Delivered-To: apmail-directory-api-archive@directory.apache.org
Received: (qmail 31213 invoked by uid 500); 13 Jan 2010 23:44:07 -0000
Mailing-List: contact api-help@directory.apache.org; run by ezmlm
Precedence: bulk
List-Help:
List-Unsubscribe:
List-Post:
List-Id:
Reply-To: api@directory.apache.org
Delivered-To: mailing list api@directory.apache.org
Received: (qmail 31203 invoked by uid 99); 13 Jan 2010 23:44:07 -0000
Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Jan 2010 23:44:07 +0000
X-ASF-Spam-Status: No, hits=-0.0 required=10.0
tests=SPF_PASS
X-Spam-Check-By: apache.org
Received-SPF: pass (nike.apache.org: domain of elecharny@gmail.com designates 209.85.219.217 as permitted sender)
Received: from [209.85.219.217] (HELO mail-ew0-f217.google.com) (209.85.219.217)
by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Jan 2010 23:43:57 +0000
Received: by ewy9 with SMTP id 9so7753483ewy.11
for ; Wed, 13 Jan 2010 15:43:37 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=gamma;
h=domainkey-signature:received:received:message-id:date:from
:user-agent:mime-version:to:subject:references:in-reply-to
:content-type:content-transfer-encoding;
bh=uN5kw9d8C3D9c719BadUy45HO4QhwB9tAxhNb+m5jgo=;
b=lfcyfOMkCbNhUJrZb82VIn0cgve+tiZzRaQod6GG3fIw6MeW7qLnHJGn1Via5H+lQm
thUAGGki8/moBjfPzkdWlw2Tnaf/ldy8TkbTEnItO9HE4dzuZbUzedeHLvJw04Odulvv
zhRVZs1317oT9iKlzPi9qOBmLqIdeHBMWBaxI=
DomainKey-Signature: a=rsa-sha1; c=nofws;
d=gmail.com; s=gamma;
h=message-id:date:from:user-agent:mime-version:to:subject:references
:in-reply-to:content-type:content-transfer-encoding;
b=vPb+NMEUQlzjORSlwSMUkqZDDFWKRxL3vP0XqOx7ZGmEuaEt1bm43k8OLFtk/54UtW
DXQDq5IrEjmZPk70tHK5nu2QZhiEUPggzefHCe0aVKk6Z+p9DGRWwYaUa4EGUmO2poJ7
8Bkrvf1gJsCAdsEOAmy1p/R6eH5oNtLB3Lw94=
Received: by 10.213.39.203 with SMTP id h11mr1887703ebe.0.1263426217151;
Wed, 13 Jan 2010 15:43:37 -0800 (PST)
Received: from emmanuel-lecharnys-MacBook-Pro.local (ver78-3-89-80-150-189.dsl.club-internet.fr [89.80.150.189])
by mx.google.com with ESMTPS id 23sm136213eya.43.2010.01.13.15.43.35
(version=TLSv1/SSLv3 cipher=RC4-MD5);
Wed, 13 Jan 2010 15:43:35 -0800 (PST)
Message-ID: <4B4E5AA6.7060907@gmail.com>
Date: Thu, 14 Jan 2010 00:43:34 +0100
From: =?UTF-8?B?RW1tYW51ZWwgTMKOY2hhcm55?=
User-Agent: Thunderbird 2.0.0.23 (Macintosh/20090812)
MIME-Version: 1.0
To: api@directory.apache.org
Subject: Re: [DN] Existing API review
References: <4B4C7948.3000503@gmail.com> <4B4DAD6E.4040204@sun.com>
In-Reply-To: <4B4DAD6E.4040204@sun.com>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Virus-Checked: Checked by ClamAV on apache.org
Matthew Swift a écrit :
> Hi Emmanuel,
Hi Matthew,
comments inline
>
>
>> 2) In Java, it's pretty natural to create objects through constructor.
>
>
> This may be true for constructors which compose the constructor's
> parameters (e.g. list of RDNs or RDN+DN) into a new object (DN), but
> it is definitely not true for constructors which perform parsing or
> type conversions. There are very many examples in J2SE:
>
> * String.valueOf(...) -converting objects to Strings
>
> * Integer.valueOf(int) - converting an int to an Integer
>
> * Integer.valueOf(String) - parsing a String as an Integer
>
> * plus other primitive Objects (Boolean, Byte, Char, Float, ...)
>
>
> In fact, the use of static factory methods is a very common design
> idiom and is strongly recommended in many texts including Joshua
> Bloch's "Effective Java" (item #1). By using static factories with
> well known names (e.g. valueOf) we are able to avoid creating
> duplicate objects (item 4) if this proves useful (i.e. through the use
> of a cache) and also enforce the singleton property for the root DN
> (item #2).
In any case, I thinkw e should have the constructors. Even for Integer,
you can do new Integer(n).
>> 3) I'm not sure that handling a cache for DN is a valuable trick, as it
>> leads to some contention and the need to manage this cache in a
>> muli-threaded environement (this has to be carefully evaluated)
>>
>
> I have done already and it results in a 30-40% parsing performance
> improvement as well as a significant reduction in garbage. Having said
> that, I'm not totally convinced that this gain is really worth the
> extra complexity and old generation memory usage - especially
> considering large server based applications may have 1000s of threads
> - e.g using LDAP from within a servlet - all those thread local caches
> could use a significant amount of memory!
>
> Our implementation uses a small thread/schema local cache mapping
> String values to DNs. In most applications I think that it's
> reasonable to assume that 99% (perhaps more) DNs share the same parent
> or grand parent. When parsing a DN we first check if the string is in
> the cache and, if not, parse the RDN and recursively repeat for the
> parent DN (in the SDK a DN is implemented recursively as an RDN+DN).
Well, I don't really think that it's anything but implementation
dependent, so from the API POV, it's irrelevant. As soon as we add the
valueof() methods, those who want to add a cache can do it.
I don't know why I raised this point...
>
>> The base constructor we can have are probably something like:
>> DN()
>> DN(String dnStr)
>> DN( RDN... rdns)
>> DN( RDN rdn, DN parent)
>>
>
>
> I like the DN( RDN rdn, DN parent) constructor - we support this via
> an instance method called DN.child(RDN). I think I prefer the
> constructor approach since it is not clear from our "child" method
> whether or not it modifies this DN or creates a new DN. A constructor
> is more obvious. You may want to have a concatenation constructor
> DN(DN child, DN parent) for constructing DNs of entries within a
> subtree using a relative DN (or "local name").
Why not a DN(DN child, DN parent) constructor two. It does not hurt and
can help.
>
> One thing that is a bit tricky is whether or not the API should order
> RDN parameters in little-endian (LDAP World) order or big-endian
> (everyone else outside of LDAP) order. I think first time users may be
> surprised by LDAP's unnatural little endian ordering.
I think we should keep the LDAP order when using DN( RDN...)
constructor. For instance, if we want to create "dc=example, dc=org",
that would be :
DN( "dc=example", "dc=org") (here, I use the String, but you should read
RDN)
>
> Also, I strongly believe that DNs and RDNs and AVAs should be
> immutable objects (as well as any other low level API type). What do
> you think?
DN and RDN should be immutable, sure. AVA, I have some doubt.
>
> Also, on the subject of AVAs - we have the AVA type as an inner class
> in RDN. I'm not particularly happy with this this, but less happy with
> it being a standalone class since AVAs are only used in RDNs and may
> introduce confusion elsewhere. For example, filters also use attribute
> value assertions but these are not the same type of object as an AVA
> even if they have the same name. For example, AVAs (in RDNs) do not
> allow attribute options or matching rules to be specified.
I don't really like inner classes in this case for two reasons :
- It will be a big class, and the RN class while be hundreds of line
long. Not cool
- If we just use an Inner class just because we want to hide it from the
other classes, then I think it's probably better to have it package
protected (ie, no qualifier for this class).
This can be discussed further, as your pont about its use in other
context can be figured out.
Thanks !