Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 25998 invoked from network); 17 May 2010 12:26:49 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 17 May 2010 12:26:49 -0000 Received: (qmail 61413 invoked by uid 500); 17 May 2010 12:26:49 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 61331 invoked by uid 500); 17 May 2010 12:26:48 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 61321 invoked by uid 99); 17 May 2010 12:26:47 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 17 May 2010 12:26:47 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 17 May 2010 12:26:45 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 990D923889E5; Mon, 17 May 2010 12:26:23 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r945110 - in /couchdb/trunk/src/couchdb: couch_file.erl priv/icu_driver/couch_icu_driver.c Date: Mon, 17 May 2010 12:26:23 -0000 To: commits@couchdb.apache.org From: kocolosk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100517122623.990D923889E5@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kocolosk Date: Mon May 17 12:26:23 2010 New Revision: 945110 URL: http://svn.apache.org/viewvc?rev=945110&view=rev Log: use O_APPEND to skip some lseeks, COUCHDB-754 Modified: couchdb/trunk/src/couchdb/couch_file.erl couchdb/trunk/src/couchdb/priv/icu_driver/couch_icu_driver.c Modified: couchdb/trunk/src/couchdb/couch_file.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_file.erl?rev=945110&r1=945109&r2=945110&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_file.erl (original) +++ couchdb/trunk/src/couchdb/couch_file.erl Mon May 17 12:26:23 2010 @@ -19,7 +19,8 @@ -record(file, { fd, - tail_append_begin=0 % 09 UPGRADE CODE + tail_append_begin = 0, % 09 UPGRADE CODE + eof = 0 }). -export([open/1, open/2, close/1, bytes/1, sync/1, append_binary/2,old_pread/3]). @@ -204,7 +205,7 @@ init({Filepath, Options, ReturnPid, Ref} case lists:member(create, Options) of true -> filelib:ensure_dir(Filepath), - case file:open(Filepath, [read, write, raw, binary]) of + case file:open(Filepath, [read, append, raw, binary]) of {ok, Fd} -> {ok, Length} = file:position(Fd, eof), case Length > 0 of @@ -236,10 +237,11 @@ init({Filepath, Options, ReturnPid, Ref} % open in read mode first, so we don't create the file if it doesn't exist. case file:open(Filepath, [read, raw]) of {ok, Fd_Read} -> - {ok, Fd} = file:open(Filepath, [read, write, raw, binary]), + {ok, Fd} = file:open(Filepath, [read, append, raw, binary]), ok = file:close(Fd_Read), couch_stats_collector:track_process_count({couchdb, open_os_files}), - {ok, #file{fd=Fd}}; + {ok, Length} = file:position(Fd, eof), + {ok, #file{fd=Fd, eof=Length}}; Error -> init_status_error(ReturnPid, Ref, Error) end @@ -269,24 +271,27 @@ handle_call({pread_iolist, Pos}, _From, handle_call({pread, Pos, Bytes}, _From, #file{fd=Fd,tail_append_begin=TailAppendBegin}=File) -> {ok, Bin} = file:pread(Fd, Pos, Bytes), {reply, {ok, Bin, Pos >= TailAppendBegin}, File}; -handle_call(bytes, _From, #file{fd=Fd}=File) -> - {reply, file:position(Fd, eof), File}; +handle_call(bytes, _From, #file{eof=Length}=File) -> + {reply, {ok, Length}, File}; handle_call(sync, _From, #file{fd=Fd}=File) -> {reply, file:sync(Fd), File}; handle_call({truncate, Pos}, _From, #file{fd=Fd}=File) -> {ok, Pos} = file:position(Fd, Pos), - {reply, file:truncate(Fd), File}; -handle_call({append_bin, Bin}, _From, #file{fd=Fd}=File) -> - {ok, Pos} = file:position(Fd, eof), + case file:truncate(Fd) of + ok -> + {reply, ok, File#file{eof=Pos}}; + Error -> + {reply, Error, File} + end; +handle_call({append_bin, Bin}, _From, #file{fd=Fd, eof=Pos}=File) -> Blocks = make_blocks(Pos rem ?SIZE_BLOCK, Bin), - case file:pwrite(Fd, Pos, Blocks) of + case file:write(Fd, Blocks) of ok -> - {reply, {ok, Pos}, File}; + {reply, {ok, Pos}, File#file{eof=Pos+iolist_size(Blocks)}}; Error -> {reply, Error, File} end; -handle_call({write_header, Bin}, _From, #file{fd=Fd}=File) -> - {ok, Pos} = file:position(Fd, eof), +handle_call({write_header, Bin}, _From, #file{fd=Fd, eof=Pos}=File) -> BinSize = size(Bin), case Pos rem ?SIZE_BLOCK of 0 -> @@ -295,13 +300,18 @@ handle_call({write_header, Bin}, _From, Padding = <<0:(8*(?SIZE_BLOCK-BlockOffset))>> end, FinalBin = [Padding, <<1, BinSize:32/integer>> | make_blocks(1, [Bin])], - {reply, file:pwrite(Fd, Pos, FinalBin), File}; + case file:write(Fd, FinalBin) of + ok -> + {reply, ok, File#file{eof=Pos+iolist_size(FinalBin)}}; + Error -> + {reply, Error, File} + end; handle_call({upgrade_old_header, Prefix}, _From, #file{fd=Fd}=File) -> case (catch read_old_header(Fd, Prefix)) of {ok, Header} -> - {ok, TailAppendBegin} = file:position(Fd, eof), + TailAppendBegin = File#file.eof, Bin = term_to_binary(Header), Md5 = couch_util:md5(Bin), % now we assemble the final header binary and write to disk @@ -319,8 +329,7 @@ handle_call({upgrade_old_header, Prefix} end; -handle_call(find_header, _From, #file{fd=Fd}=File) -> - {ok, Pos} = file:position(Fd, eof), +handle_call(find_header, _From, #file{fd=Fd, eof=Pos}=File) -> {reply, find_header(Fd, Pos div ?SIZE_BLOCK), File}. % 09 UPGRADE CODE Modified: couchdb/trunk/src/couchdb/priv/icu_driver/couch_icu_driver.c URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/priv/icu_driver/couch_icu_driver.c?rev=945110&r1=945109&r2=945110&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/priv/icu_driver/couch_icu_driver.c (original) +++ couchdb/trunk/src/couchdb/priv/icu_driver/couch_icu_driver.c Mon May 17 12:26:23 2010 @@ -27,8 +27,11 @@ specific language governing permissions #include "unicode/ucasemap.h" #ifndef WIN32 #include // for memcpy +#include // for O_DSYNC #endif +#define SET_OSYNC_OPCODE 2 + typedef struct { ErlDrvPort port; UCollator* collNoCase; @@ -90,6 +93,19 @@ static int return_control_result(void* p return localLen; } +static char set_osync(int fd) { + int flags = fcntl(fd, F_GETFL, 0); + if (flags != -1) { + if (fcntl(fd, F_SETFL, flags | O_DSYNC) != -1) { + return 0; + } else { + return 1; + } + } else { + return 2; + } +} + static int couch_drv_control(ErlDrvData drv_data, unsigned int command, char *pBuf, int bufLen, char **rbuf, int rlen) { @@ -141,6 +157,14 @@ static int couch_drv_control(ErlDrvData return return_control_result(&response, sizeof(response), rbuf, rlen); } + case SET_OSYNC_OPCODE: // set O_SYNC flag on file descriptor + { + int32_t fd; + memcpy(&fd, pBuf, sizeof(fd)); + char response = set_osync(fd); + return return_control_result(&response, sizeof(response), rbuf, rlen); + } + default: return -1; }