Return-Path: Delivered-To: apmail-directory-dev-archive@www.apache.org Received: (qmail 43687 invoked from network); 25 May 2010 11:41:39 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 25 May 2010 11:41:39 -0000 Received: (qmail 58041 invoked by uid 500); 25 May 2010 11:41:38 -0000 Delivered-To: apmail-directory-dev-archive@directory.apache.org Received: (qmail 57913 invoked by uid 500); 25 May 2010 11:41:37 -0000 Mailing-List: contact dev-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Apache Directory Developers List" Delivered-To: mailing list dev@directory.apache.org Received: (qmail 57906 invoked by uid 99); 25 May 2010 11:41:36 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 May 2010 11:41:36 +0000 X-ASF-Spam-Status: No, hits=-0.1 required=10.0 tests=AWL,FREEMAIL_FROM,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of elecharny@gmail.com designates 74.125.82.178 as permitted sender) Received: from [74.125.82.178] (HELO mail-wy0-f178.google.com) (74.125.82.178) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 May 2010 11:41:30 +0000 Received: by wya21 with SMTP id 21so372887wya.37 for ; Tue, 25 May 2010 04:41:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:reply-to :user-agent:mime-version:to:subject:content-type :content-transfer-encoding; bh=w+PiQaL7GNsV/S/AuavhTW5lTqMBIL7OruHSV04CssY=; b=PDY4+BFiRfQowte5UXee+cWS+rtQv4+yRKhKwzm0L0hZHa+VlG9wMETPVLgVrZ8qOb Dnvl7yHnl7VxK/SKPuo02kYX7jt7TLgYv+x3py2IIRk+uC6r3LmZO9coJx0/fFRdA6dh GnCDn6jRN0zN3h0iXgLVGgp4klQVg/eh4Ulvc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:reply-to:user-agent:mime-version:to:subject :content-type:content-transfer-encoding; b=SS4jNv1TD3xCp5oe5/l82xC4Bv+cpz+osoajwJyK09HvNTcQNnSD8pqa+KD/bv7mQ6 faKrDRKRRfWjWu3A6/s9YS5J75grz6v5pvJodOnzKAJA1aah7kwdGXUSGtFmhz6zwVov oZidHfBiArWqcNYVGR9s8c7WvwRzWv5AQU29E= Received: by 10.227.133.148 with SMTP id f20mr6876016wbt.207.1274787668882; Tue, 25 May 2010 04:41:08 -0700 (PDT) Received: from emmanuel-lecharnys-MacBook-Pro.local (vol75-3-82-66-216-176.fbx.proxad.net [82.66.216.176]) by mx.google.com with ESMTPS id z33sm38912968wbd.19.2010.05.25.04.41.07 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 25 May 2010 04:41:08 -0700 (PDT) Message-ID: <4BFB955E.2070602@gmail.com> Date: Tue, 25 May 2010 11:16:14 +0200 From: Emmanuel Lecharny Reply-To: elecharny@apache.org User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4 MIME-Version: 1.0 To: Apache Directory Developers List Subject: About index and atomic operations Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit Hi guys, as I'm currently reviewing the JDBM code, I think we might get better performance if we use another solution than brutal synchronization (also the current implementation is not 100% threadsafe). Right now, the AbstractStore is the class responsible for accessing the entries, and update the DIT. As we must provide operation atomicity, we have synchronized those methods : - add(entry) - delete(DN) - modify() - move() - rename() All the other methods aren't synchronized, so for instance calling getUserIndex() does not guarantee that the returned index is protected against concurrent modifications. In fact, we must see an operation as atomic, which means no other thread can access the modified index and data while the operation is not completely done. JDBM does not offer such a level of protection. In order to guarantee atomic operations, we should instead implement a system based on MVCC (Multiple Version Concurrent Control), where all the reads are done expecting that the data hasn't been modified since the operation started (avoiding costly locks to be used), and a two steps modification : - first locally modify the data structure (nothing is locked until all the modified elements are updated in memory). That means we read from the disk and store in memory the necessary elements for this operation. - then when done, acquire a global lock and update the data structure for all the modified elements Doing so will allow us to spare a lot of contention, as we only update the modified elements (ie, if we add an entry, the associated BTrees index won't necessary be updated from root to leaves. Usually, only one leaf is modified), restricting the time necessary to do the commit to the minimum. In any case, read are not synchronized, we just return what is present in the backend using the latest version. Obviously, we can get an error if for instance we are reading all the children of an entry, and if this entry is deleted since the operation started, but that's not a problem: there is no guarantee in LDAP that a returned resut is stil present in the DIT. In order to do that, we will associate a version to each element we store, so we just have to compare the element version with the latest version for this element. Ok, this is a rough description of the whole mechanism, but that should work well. -- Regards, Cordialement, Emmanuel L�charny www.nextury.com