QueryResponses.cs, DumpIndex.cs, IQueryResult.cs, QueryExecutor.cs, QueryResult.cs...
[beagle.git] / beagled / Lucene.Net / upstream-changes / 01_obtain-lock-fix.patch
blob3e3546cdb0feeafb4e702642a10d066512230fc3
1 From: Debajyoti Bera <dbera.web@gmail.com>
3 Lucene uses lockfiles for sharing index files across multiple processes. Stock
4 lucene.net implementation creates the lockfile incorrectly.
5 01_obtain-lock-fix.patch fixes that but leaves a small race window. This
6 patch removes the race window. It uses native open() syscall instead of
7 System.IO File operations as the mono implementations for File.Open() turned
8 out to be buggy (giving wrong sharing violation errors).
10 Updated by: Joe Shaw <joeshaw@novell.com>
12 My update to this patch redoes the way the locking PID was being written out
13 to disk. We were doing it previously using a UnixStream and StreamWriter,
14 but that turned out to be very slow and put a noticable dent in indexing
15 performance. This new version uses POSIX I/O calls directly to write out
16 the PID and it resolves the performance issue.
18 From: Joe Shaw <joeshaw@novell.com>
20 FileExists() gets called a *lot*. We can avoid a bunch of string
21 allocations inherent in creating a FileInfo object by just using
22 File.Exists() rather than FileInfo.Exists(). Unfortunately we can't
23 seem to avoid the allocation of the Path.Combine().
25 Index: Store/FSDirectory.cs
26 ===================================================================
27 RCS file: /cvs/gnome/beagle/beagled/Lucene.Net/Store/FSDirectory.cs,v
28 retrieving revision 1.19.2.13
29 diff -u -3 -p -r1.19.2.13 FSDirectory.cs
30 --- Store/FSDirectory.cs 25 Sep 2006 22:54:07 -0000 1.19.2.13
31 +++ Store/FSDirectory.cs 25 Sep 2006 22:55:51 -0000
32 @@ -16,6 +16,7 @@
34 using System;
35 using IndexFileNameFilter = Lucene.Net.Index.IndexFileNameFilter;
36 +using Mono.Unix.Native;
38 namespace Lucene.Net.Store
40 @@ -52,6 +53,7 @@ namespace Lucene.Net.Store
42 public override bool Obtain()
44 + Log ("Trying to obtain lock " + lockFile.FullName);
45 if (Lucene.Net.Store.FSDirectory.disableLocks)
46 return true;
48 @@ -71,15 +73,61 @@ namespace Lucene.Net.Store
49 throw new System.IO.IOException("Cannot create lock directory: " + Enclosing_Instance.lockDir);
54 try
56 + int fd = Mono.Unix.Native.Syscall.open (
57 + lockFile.FullName,
58 + Mono.Unix.Native.OpenFlags.O_RDWR |
59 + Mono.Unix.Native.OpenFlags.O_CREAT |
60 + Mono.Unix.Native.OpenFlags.O_EXCL,
61 + Mono.Unix.Native.FilePermissions.S_IRUSR);
62 + if (fd == -1)
63 + throw new System.IO.IOException ("Could not create lock file: "
64 + + Mono.Unix.Native.Stdlib.strerror (
65 + Mono.Unix.Native.Stdlib.GetLastError ()
66 + ));
68 + // This code replaces the commented-out code below because
69 + // it ends up being much faster. The reason for this is
70 + // that closing a UnixStream causes Syscall.fsync() to be
71 + // called, and that apparently is extremely slow!
72 + //
73 + // Time(ms) Count P/call(ms) Method name
74 + // 1563.926 68 22.999 Mono.Unix.Native.Syscall::fsync(int)
75 + //
76 + // Since the lock file is written out very often, this time
77 + // adds up and noticably slows down indexing.
78 + IntPtr ptr = IntPtr.Zero;
79 + long ret;
81 + try {
82 + string s = System.Diagnostics.Process.GetCurrentProcess ().Id.ToString () + "\n";
83 + ptr = Mono.Unix.UnixMarshal.StringToHeap (s);
85 + do {
86 + ret = Mono.Unix.Native.Syscall.write (fd, ptr, (ulong) s.Length);
87 + } while (Mono.Unix.UnixMarshal.ShouldRetrySyscall ((int) ret));
88 + Mono.Unix.UnixMarshal.ThrowExceptionForLastErrorIf ((int) ret);
89 + } finally {
90 + Mono.Unix.UnixMarshal.FreeHeap (ptr);
92 + do {
93 + ret = Mono.Unix.Native.Syscall.close (fd);
94 + } while (Mono.Unix.UnixMarshal.ShouldRetrySyscall ((int) ret));
95 + Mono.Unix.UnixMarshal.ThrowExceptionForLastErrorIf ((int) ret);
96 + }
98 + //System.IO.StreamWriter w = new System.IO.StreamWriter (new Mono.Unix.UnixStream (fd, true));
99 + //w.WriteLine (System.Diagnostics.Process.GetCurrentProcess ().Id);
100 + //w.Close ();
101 System.IO.FileStream createdFile = lockFile.Create();
102 createdFile.Close();
103 return true;
105 - catch (Exception)
106 + catch (Exception e)
108 + Log ("Exception in CreateNew for file:" + lockFile.FullName + ":" + e);
109 return false;
112 @@ -100,7 +148,15 @@ namespace Lucene.Net.Store
114 else
115 tmpBool = false;
116 + if (System.IO.File.Exists(lockFile.FullName)) {
117 + Log ("Release didnt delete lockfile {0}.", lockFile.FullName);
118 + tmpBool = false;
120 bool generatedAux = tmpBool;
121 + if (tmpBool)
122 + Log ("Released lock {0}", lockFile.FullName);
123 + else
124 + Log ("Failed to release lock {0}", lockFile.FullName);
126 public override bool IsLocked()
128 @@ -365,13 +421,9 @@ namespace Lucene.Net.Store
129 /// <summary>Returns true iff a file with the given name exists. </summary>
130 public override bool FileExists(System.String name)
132 - System.IO.FileInfo file = new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name));
133 - bool tmpBool;
134 - if (System.IO.File.Exists(file.FullName))
135 - tmpBool = true;
136 - else
137 - tmpBool = System.IO.Directory.Exists(file.FullName);
138 - return tmpBool;
139 + string path = System.IO.Path.Combine (directory.FullName, name);
141 + return System.IO.File.Exists (path) || System.IO.Directory.Exists (path);
144 /// <summary>Returns the time the named file was last modified. </summary>
145 @@ -571,6 +623,20 @@ namespace Lucene.Net.Store
146 return new FSIndexInput(new System.IO.FileInfo(System.IO.Path.Combine(directory.FullName, name)));
149 + static public Beagle.Util.Logger Logger = null;
150 + //static public Beagle.Util.Logger Logger = Beagle.Util.Logger.Log;
151 + static public void Log (string format, params object[] args)
153 + if (Logger != null)
154 + Logger.Debug (format, args);
157 + static public void Log (Exception e)
159 + if (Logger != null)
160 + Logger.Debug (e);
163 /// <summary> So we can do some byte-to-hexchar conversion below</summary>
164 private static readonly char[] HEX_DIGITS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
166 @@ -828,4 +894,4 @@ namespace Lucene.Net.Store
167 file.Close(); // close the file
171 \ No newline at end of file