Repository: lucy
Updated Branches:
  refs/heads/master 7a64a288c -> d7feb9970


Rework snapshot and deletion locks

Request exclusive or shared snapshot locks instead of the global
deletion lock. This removes the need to retry lock requests and
reduces contention.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/5270b988
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/5270b988
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/5270b988

Branch: refs/heads/master
Commit: 5270b988c477a2e1c110e2069c66bb2d3f27a60f
Parents: 79161a4
Author: Nick Wellnhofer <wellnho...@aevum.de>
Authored: Fri Feb 17 17:19:43 2017 +0100
Committer: Nick Wellnhofer <wellnho...@aevum.de>
Committed: Mon Feb 20 16:26:21 2017 +0100

----------------------------------------------------------------------
 core/Lucy/Index/FilePurger.c     | 133 ++++++++++++++++------------------
 core/Lucy/Index/IndexManager.c   |  43 +----------
 core/Lucy/Index/IndexManager.cfh |  32 +-------
 core/Lucy/Index/IndexReader.c    |  18 ++---
 core/Lucy/Index/IndexReader.cfh  |   3 +-
 core/Lucy/Index/PolyReader.c     | 123 ++++++++++++-------------------
 go/lucy/index_test.go            |  13 +---
 perl/t/109-read_locking.t        |  53 ++++++--------
 perl/t/111-index_manager.t       |   7 +-
 9 files changed, 145 insertions(+), 280 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/core/Lucy/Index/FilePurger.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/FilePurger.c b/core/Lucy/Index/FilePurger.c
index 6811c33..433dec3 100644
--- a/core/Lucy/Index/FilePurger.c
+++ b/core/Lucy/Index/FilePurger.c
@@ -33,7 +33,7 @@
 // obsolete snapshots to snapshots array.
 static void
 S_discover_unused(FilePurger *self, Snapshot *current, Hash *spared,
-                  Hash *purged, Vector *snapshots);
+                  Hash *purged, Vector *snapshots, Vector *locks);
 
 // Add filepath entries referenced by a snapshot to a Hash. Note that
 // it's assumed that snapshots only list entries local to the index
@@ -75,69 +75,65 @@ FilePurger_Destroy_IMP(FilePurger *self) {
 void
 FilePurger_Purge_Snapshots_IMP(FilePurger *self, Snapshot *current) {
     FilePurgerIVARS *const ivars = FilePurger_IVARS(self);
-    Lock *deletion_lock = IxManager_Make_Deletion_Lock(ivars->manager);
-
-    // Obtain deletion lock, purge files, release deletion lock.
-    if (Lock_Obtain_Exclusive(deletion_lock)) {
-        Folder *folder    = ivars->folder;
-        Hash   *failures  = Hash_new(16);
-        Hash   *spared    = Hash_new(32);
-        Hash   *purged    = Hash_new(32);
-        Vector *snapshots = Vec_new(16);
-
-        // Don't allow the locks directory to be zapped.
-        Hash_Store_Utf8(spared, "locks", 5, (Obj*)CFISH_TRUE);
-
-        S_discover_unused(self, current, spared, purged, snapshots);
-
-        // Attempt to delete entries -- if failure, no big deal, just try
-        // again later.
-        HashIterator *iter = HashIter_new(purged);
-        while (HashIter_Next(iter)) {
-            String *entry = HashIter_Get_Key(iter);
-            if (Hash_Fetch(spared, entry)) { continue; }
-            if (!S_delete_entry(folder, entry)) {
-                if (Folder_Exists(folder, entry)) {
-                    Hash_Store(failures, entry, (Obj*)CFISH_TRUE);
-                }
+
+    Folder *folder    = ivars->folder;
+    Hash   *failures  = Hash_new(16);
+    Hash   *spared    = Hash_new(32);
+    Hash   *purged    = Hash_new(32);
+    Vector *snapshots = Vec_new(16);
+    Vector *locks     = Vec_new(16);
+
+    // Don't allow the locks directory to be zapped.
+    Hash_Store_Utf8(spared, "locks", 5, (Obj*)CFISH_TRUE);
+
+    S_discover_unused(self, current, spared, purged, snapshots, locks);
+
+    // Attempt to delete entries -- if failure, no big deal, just try
+    // again later.
+    HashIterator *iter = HashIter_new(purged);
+    while (HashIter_Next(iter)) {
+        String *entry = HashIter_Get_Key(iter);
+        if (Hash_Fetch(spared, entry)) { continue; }
+        if (!S_delete_entry(folder, entry)) {
+            if (Folder_Exists(folder, entry)) {
+                Hash_Store(failures, entry, (Obj*)CFISH_TRUE);
             }
         }
+    }
 
-        for (size_t i = 0, max = Vec_Get_Size(snapshots); i < max; i++) {
-            Snapshot *snapshot = (Snapshot*)Vec_Fetch(snapshots, i);
-            bool snapshot_has_failures = false;
-            if (Hash_Get_Size(failures)) {
-                // Only delete snapshot files if all of their entries were
-                // successfully deleted.
-                Vector *entries = Snapshot_List(snapshot);
-                for (size_t j = Vec_Get_Size(entries); j--;) {
-                    String *entry = (String*)Vec_Fetch(entries, j);
-                    if (Hash_Fetch(failures, entry)) {
-                        snapshot_has_failures = true;
-                        break;
-                    }
+    for (size_t i = 0, max = Vec_Get_Size(snapshots); i < max; i++) {
+        Snapshot *snapshot = (Snapshot*)Vec_Fetch(snapshots, i);
+        bool snapshot_has_failures = false;
+        if (Hash_Get_Size(failures)) {
+            // Only delete snapshot files if all of their entries were
+            // successfully deleted.
+            Vector *entries = Snapshot_List(snapshot);
+            for (size_t j = Vec_Get_Size(entries); j--;) {
+                String *entry = (String*)Vec_Fetch(entries, j);
+                if (Hash_Fetch(failures, entry)) {
+                    snapshot_has_failures = true;
+                    break;
                 }
-                DECREF(entries);
-            }
-            if (!snapshot_has_failures) {
-                String *snapfile = Snapshot_Get_Path(snapshot);
-                Folder_Local_Delete(folder, snapfile);
             }
+            DECREF(entries);
+        }
+        if (!snapshot_has_failures) {
+            String *snapfile = Snapshot_Get_Path(snapshot);
+            Folder_Local_Delete(folder, snapfile);
         }
-
-        DECREF(iter);
-        DECREF(failures);
-        DECREF(purged);
-        DECREF(spared);
-        DECREF(snapshots);
-        Lock_Release(deletion_lock);
     }
-    else {
-        WARN("Can't obtain deletion lock, skipping deletion of "
-             "obsolete files");
+
+    // Release snapshot locks.
+    for (size_t i = 0, max = Vec_Get_Size(locks); i < max; i++) {
+        Lock_Release((Lock*)Vec_Fetch(locks, i));
     }
 
-    DECREF(deletion_lock);
+    DECREF(iter);
+    DECREF(failures);
+    DECREF(purged);
+    DECREF(spared);
+    DECREF(snapshots);
+    DECREF(locks);
 }
 
 void
@@ -185,7 +181,7 @@ FilePurger_Purge_Aborted_Merge_IMP(FilePurger *self) {
 
 static void
 S_discover_unused(FilePurger *self, Snapshot *current, Hash *spared,
-                  Hash *purged, Vector *snapshots) {
+                  Hash *purged, Vector *snapshots, Vector *locks) {
     FilePurgerIVARS *const ivars = FilePurger_IVARS(self);
     Folder      *folder       = ivars->folder;
     DirHandle   *dh           = Folder_Open_Dir(folder, NULL);
@@ -206,26 +202,23 @@ S_discover_unused(FilePurger *self, Snapshot *current, 
Hash *spared,
         ) {
             Snapshot *snapshot
                 = Snapshot_Read_File(Snapshot_new(), folder, entry);
-            Lock *lock
-                = IxManager_Make_Snapshot_Read_Lock(ivars->manager, entry);
+            Lock *lock = IxManager_Make_Snapshot_Lock(ivars->manager, entry);
 
-            // DON'T obtain the lock -- only see whether another
-            // entity holds a lock on the snapshot file.
-            if (lock && Lock_Is_Locked(lock)) {
+            if (Lock_Request_Exclusive(lock)) {
+                // No one's using this snapshot, so all of its entries are
+                // candidates for deletion.
+                Vec_Push(snapshots, (Obj*)snapshot);
+                Vec_Push(locks, (Obj*)lock);
+                S_find_all_referenced(snapshot, purged);
+            }
+            else {
                 // The snapshot file is locked, which means someone's using
                 // that version of the index -- protect all of its entries.
                 Hash_Store(spared, entry, (Obj*)CFISH_TRUE);
                 S_find_all_referenced(snapshot, spared);
+                DECREF(snapshot);
+                DECREF(lock);
             }
-            else {
-                // No one's using this snapshot, so all of its entries are
-                // candidates for deletion.
-                Vec_Push(snapshots, INCREF(snapshot));
-                S_find_all_referenced(snapshot, purged);
-            }
-
-            DECREF(snapshot);
-            DECREF(lock);
         }
         DECREF(entry);
     }

http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/core/Lucy/Index/IndexManager.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/IndexManager.c b/core/Lucy/Index/IndexManager.c
index 82b9012..bd3aa30 100644
--- a/core/Lucy/Index/IndexManager.c
+++ b/core/Lucy/Index/IndexManager.c
@@ -99,8 +99,6 @@ IxManager_init(IndexManager *self, String *host) {
     ivars->write_lock_interval = 100;
     ivars->merge_lock_timeout  = 0;
     ivars->merge_lock_interval = 1000;
-    ivars->deletion_lock_timeout  = 1000;
-    ivars->deletion_lock_interval = 100;
 
     return self;
 }
@@ -263,16 +261,6 @@ IxManager_Make_Write_Lock_IMP(IndexManager *self) {
 }
 
 Lock*
-IxManager_Make_Deletion_Lock_IMP(IndexManager *self) {
-    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
-    String *lock_name = SSTR_WRAP_C("deletion");
-    return (Lock*)LFLock_new(ivars->folder, lock_name, ivars->host,
-                             (int32_t)ivars->deletion_lock_timeout,
-                             (int32_t)ivars->deletion_lock_interval,
-                             true);
-}
-
-Lock*
 IxManager_Make_Merge_Lock_IMP(IndexManager *self) {
     IndexManagerIVARS *const ivars = IxManager_IVARS(self);
     String *merge_lock_name = SSTR_WRAP_C("merge");
@@ -323,8 +311,7 @@ IxManager_Remove_Merge_Data_IMP(IndexManager *self) {
 }
 
 Lock*
-IxManager_Make_Snapshot_Read_Lock_IMP(IndexManager *self,
-                                      String *filename) {
+IxManager_Make_Snapshot_Lock_IMP(IndexManager *self, String *filename) {
     IndexManagerIVARS *const ivars = IxManager_IVARS(self);
 
     if (!Str_Starts_With_Utf8(filename, "snapshot_", 9)
@@ -382,16 +369,6 @@ IxManager_Get_Merge_Lock_Interval_IMP(IndexManager *self) {
     return IxManager_IVARS(self)->merge_lock_interval;
 }
 
-uint32_t
-IxManager_Get_Deletion_Lock_Timeout_IMP(IndexManager *self) {
-    return IxManager_IVARS(self)->deletion_lock_timeout;
-}
-
-uint32_t
-IxManager_Get_Deletion_Lock_Interval_IMP(IndexManager *self) {
-    return IxManager_IVARS(self)->deletion_lock_interval;
-}
-
 void
 IxManager_Set_Write_Lock_Timeout_IMP(IndexManager *self, uint32_t timeout) {
     if (timeout > INT32_MAX) {
@@ -424,22 +401,4 @@ IxManager_Set_Merge_Lock_Interval_IMP(IndexManager *self, 
uint32_t interval) {
     IxManager_IVARS(self)->merge_lock_interval = interval;
 }
 
-void
-IxManager_Set_Deletion_Lock_Timeout_IMP(IndexManager *self,
-                                        uint32_t timeout) {
-    if (timeout > INT32_MAX) {
-        THROW(ERR, "Timeout can't be greater than INT32_MAX: %u32", timeout);
-    }
-    IxManager_IVARS(self)->deletion_lock_timeout = timeout;
-}
-
-void
-IxManager_Set_Deletion_Lock_Interval_IMP(IndexManager *self,
-                                         uint32_t interval) {
-    if (interval > INT32_MAX) {
-        THROW(ERR, "Interval can't be greater than INT32_MAX: %u32", interval);
-    }
-    IxManager_IVARS(self)->deletion_lock_interval = interval;
-}
-
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/core/Lucy/Index/IndexManager.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/IndexManager.cfh b/core/Lucy/Index/IndexManager.cfh
index a94517d..e73ef14 100644
--- a/core/Lucy/Index/IndexManager.cfh
+++ b/core/Lucy/Index/IndexManager.cfh
@@ -35,8 +35,6 @@ public class Lucy::Index::IndexManager nickname IxManager
     uint32_t     write_lock_interval;
     uint32_t     merge_lock_timeout;
     uint32_t     merge_lock_interval;
-    uint32_t     deletion_lock_timeout;
-    uint32_t     deletion_lock_interval;
 
     /** Create a new IndexManager.
      *
@@ -104,12 +102,6 @@ public class Lucy::Index::IndexManager nickname IxManager
     incremented Lock*
     Make_Write_Lock(IndexManager *self);
 
-    /** Create the Lock which grants permission to delete obsolete snapshot
-     * files or any file listed within an existing snapshot file.
-     */
-    incremented Lock*
-    Make_Deletion_Lock(IndexManager *self);
-
     incremented Lock*
     Make_Merge_Lock(IndexManager *self);
 
@@ -129,11 +121,11 @@ public class Lucy::Index::IndexManager nickname IxManager
     bool
     Remove_Merge_Data(IndexManager *self);
 
-    /** Create a shared lock on a snapshot file, which serves as a proxy for
+    /** Create a lock on a snapshot file, which serves as a proxy for
      * all the files it lists and indicates that they must not be deleted.
      */
     incremented Lock*
-    Make_Snapshot_Read_Lock(IndexManager *self, String *filename);
+    Make_Snapshot_Lock(IndexManager *self, String *filename);
 
     /** Return the highest number for a segment directory which contains a
      * segmeta file in the snapshot.
@@ -187,26 +179,6 @@ public class Lucy::Index::IndexManager nickname IxManager
      */
     uint32_t
     Get_Merge_Lock_Interval(IndexManager *self);
-
-    /** Setter for deletion lock timeout.  Default: 1000 milliseconds.
-     */
-    void
-    Set_Deletion_Lock_Timeout(IndexManager *self, uint32_t timeout);
-
-    /** Getter for deletion lock timeout.
-     */
-    uint32_t
-    Get_Deletion_Lock_Timeout(IndexManager *self);
-
-    /** Setter for deletion lock retry interval.  Default: 100 milliseconds.
-     */
-    void
-    Set_Deletion_Lock_Interval(IndexManager *self, uint32_t timeout);
-
-    /** Getter for deletion lock retry interval.
-     */
-    uint32_t
-    Get_Deletion_Lock_Interval(IndexManager *self);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/core/Lucy/Index/IndexReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/IndexReader.c b/core/Lucy/Index/IndexReader.c
index 98ef4dc..dabb3be 100644
--- a/core/Lucy/Index/IndexReader.c
+++ b/core/Lucy/Index/IndexReader.c
@@ -55,8 +55,7 @@ IxReader_init(IndexReader *self, Schema *schema, Folder 
*folder,
     DECREF(snapshot);
     IndexReaderIVARS *const ivars = IxReader_IVARS(self);
     ivars->components     = Hash_new(0);
-    ivars->read_lock      = NULL;
-    ivars->deletion_lock  = NULL;
+    ivars->snapshot_lock  = NULL;
     if (manager) {
         ivars->manager = (IndexManager*)INCREF(manager);
         IxManager_Set_Folder(ivars->manager, ivars->folder);
@@ -81,10 +80,10 @@ IxReader_Close_IMP(IndexReader *self) {
         DECREF(iter);
         Hash_Clear(ivars->components);
     }
-    if (ivars->read_lock) {
-        Lock_Release(ivars->read_lock);
-        DECREF(ivars->read_lock);
-        ivars->read_lock = NULL;
+    if (ivars->snapshot_lock) {
+        Lock_Release(ivars->snapshot_lock);
+        DECREF(ivars->snapshot_lock);
+        ivars->snapshot_lock = NULL;
     }
 }
 
@@ -92,12 +91,11 @@ void
 IxReader_Destroy_IMP(IndexReader *self) {
     IndexReaderIVARS *const ivars = IxReader_IVARS(self);
     DECREF(ivars->components);
-    if (ivars->read_lock) {
-        Lock_Release(ivars->read_lock);
-        DECREF(ivars->read_lock);
+    if (ivars->snapshot_lock) {
+        Lock_Release(ivars->snapshot_lock);
+        DECREF(ivars->snapshot_lock);
     }
     DECREF(ivars->manager);
-    DECREF(ivars->deletion_lock);
     SUPER_DESTROY(self, INDEXREADER);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/core/Lucy/Index/IndexReader.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/IndexReader.cfh b/core/Lucy/Index/IndexReader.cfh
index 96be62a..501318c 100644
--- a/core/Lucy/Index/IndexReader.cfh
+++ b/core/Lucy/Index/IndexReader.cfh
@@ -39,8 +39,7 @@ public class Lucy::Index::IndexReader nickname IxReader
 
     Hash            *components;
     IndexManager    *manager;
-    Lock            *read_lock;
-    Lock            *deletion_lock;
+    Lock            *snapshot_lock;
 
     /** Abstract initializer.
      */

http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/core/Lucy/Index/PolyReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/PolyReader.c b/core/Lucy/Index/PolyReader.c
index ea5e35f..6b9e943 100644
--- a/core/Lucy/Index/PolyReader.c
+++ b/core/Lucy/Index/PolyReader.c
@@ -34,15 +34,11 @@
 #include "Lucy/Util/Freezer.h"
 #include "Lucy/Util/IndexFileNames.h"
 
-// Obtain/release read locks and commit locks.
+// Request/release snapshot locks.
 static bool
-S_obtain_read_lock(PolyReader *self, String *snapshot_filename);
-static bool 
-S_obtain_deletion_lock(PolyReader *self);
+S_request_snapshot_lock(PolyReader *self, String *snapshot_filename);
 static void
-S_release_read_lock(PolyReader *self);
-static void
-S_release_deletion_lock(PolyReader *self);
+S_release_snapshot_lock(PolyReader *self);
 
 // Try to open all SegReaders.
 struct try_open_elements_context {
@@ -334,19 +330,13 @@ PolyReader*
 PolyReader_do_open(PolyReader *self, Obj *index, Snapshot *snapshot,
                    IndexManager *manager) {
     PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
-    Folder   *folder   = S_derive_folder(index);
-    uint64_t  last_gen = 0;
+    Folder   *folder     = S_derive_folder(index);
+    Err      *last_error = NULL;
+    uint64_t  last_gen   = 0;
 
     PolyReader_init(self, NULL, folder, snapshot, manager, NULL);
     DECREF(folder);
 
-    if (manager) { 
-        if (!S_obtain_deletion_lock(self)) {
-            DECREF(self);
-            THROW(LOCKERR, "Couldn't get deletion lock");
-        }
-    }
-
     while (1) {
         String *target_snap_file;
 
@@ -372,12 +362,26 @@ PolyReader_do_open(PolyReader *self, Obj *index, Snapshot 
*snapshot,
         // Derive "generation" of this snapshot file from its name.
         uint64_t gen = IxFileNames_extract_gen(target_snap_file);
 
+        if (gen <= last_gen) {
+            // If a snapshot was supplied, we couldn't read it. Otherwise,
+            // no new snapshot was found which should never happen. Throw
+            // error from previous attempt to read the snapshot.
+            DECREF(self);
+            RETHROW(last_error);
+        }
+
+        last_gen = gen;
+
         // Get a read lock on the most recent snapshot file if indicated.
+        // There's no need to retry. In the unlikely case that we fail to
+        // request a lock on the latest snapshot, there must be a
+        // FilePurger deleting the snapshot, which means that a newer
+        // snapshot just became available.
         if (manager) {
-            if (!S_obtain_read_lock(self, target_snap_file)) {
-                DECREF(self);
-                THROW(LOCKERR, "Couldn't get read lock for %o",
-                      target_snap_file);
+            if (!S_request_snapshot_lock(self, target_snap_file)) {
+                // Index updated, so try again.
+                last_error = (Err*)INCREF(Err_get_error());
+                continue;
             }
         }
 
@@ -399,20 +403,13 @@ PolyReader_do_open(PolyReader *self, Obj *index, Snapshot 
*snapshot,
             context.snapshot = ivars->snapshot;
             context.folder   = folder;
             context.path     = target_snap_file;
-            Err *error = Err_trap(S_try_read_snapshot, &context);
+            last_error = Err_trap(S_try_read_snapshot, &context);
 
-            if (error) {
-                S_release_read_lock(self);
+            if (last_error) {
+                S_release_snapshot_lock(self);
                 DECREF(target_snap_file);
-                if (last_gen < gen) { // Index updated, so try again.
-                    DECREF(error);
-                    last_gen = gen;
-                    continue;
-                }
-                else { // Real error.
-                    if (manager) { S_release_deletion_lock(self); }
-                    RETHROW(error);
-                }
+                // Index updated, so try again.
+                continue;
             }
         }
 
@@ -425,18 +422,12 @@ PolyReader_do_open(PolyReader *self, Obj *index, Snapshot 
*snapshot,
         struct try_open_elements_context context;
         context.self        = self;
         context.seg_readers = NULL;
-        Err *error = Err_trap(S_try_open_elements, &context);
-        if (error) {
-            S_release_read_lock(self);
+        last_error = Err_trap(S_try_open_elements, &context);
+        if (last_error) {
+            S_release_snapshot_lock(self);
             DECREF(target_snap_file);
-            if (last_gen < gen) { // Index updated, so try again.
-                DECREF(error);
-                last_gen = gen;
-            }
-            else { // Real error.
-                if (manager) { S_release_deletion_lock(self); }
-                RETHROW(error);
-            }
+            // Index updated, so try again.
+            continue;
         }
         else { // Succeeded.
             S_init_sub_readers(self, (Vector*)context.seg_readers);
@@ -446,8 +437,6 @@ PolyReader_do_open(PolyReader *self, Obj *index, Snapshot 
*snapshot,
         }
     }
 
-    if (manager) { S_release_deletion_lock(self); }
-
     return self;
 }
 
@@ -466,49 +455,27 @@ S_derive_folder(Obj *index) {
     return folder;
 }
 
-static bool 
-S_obtain_deletion_lock(PolyReader *self) {
-    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
-    ivars->deletion_lock = IxManager_Make_Deletion_Lock(ivars->manager);
-    if (!Lock_Obtain_Exclusive(ivars->deletion_lock)) {
-        DECREF(ivars->deletion_lock);
-        ivars->deletion_lock = NULL;
-        return false;
-    }
-    return true;
-}
-
 static bool
-S_obtain_read_lock(PolyReader *self, String *snapshot_file_name) {
+S_request_snapshot_lock(PolyReader *self, String *snapshot_file_name) {
     PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
-    ivars->read_lock = IxManager_Make_Snapshot_Read_Lock(ivars->manager,
-                                                         snapshot_file_name);
+    ivars->snapshot_lock = IxManager_Make_Snapshot_Lock(ivars->manager,
+                                                        snapshot_file_name);
 
-    if (!Lock_Obtain_Shared(ivars->read_lock)) {
-        DECREF(ivars->read_lock);
-        ivars->read_lock = NULL;
+    if (!Lock_Request_Shared(ivars->snapshot_lock)) {
+        DECREF(ivars->snapshot_lock);
+        ivars->snapshot_lock = NULL;
         return false;
     }
     return true;
 }
 
 static void
-S_release_read_lock(PolyReader *self) {
-    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
-    if (ivars->read_lock) {
-        Lock_Release(ivars->read_lock);
-        DECREF(ivars->read_lock);
-        ivars->read_lock = NULL;
-    }
-}
-
-static void
-S_release_deletion_lock(PolyReader *self) {
+S_release_snapshot_lock(PolyReader *self) {
     PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
-    if (ivars->deletion_lock) {
-        Lock_Release(ivars->deletion_lock);
-        DECREF(ivars->deletion_lock);
-        ivars->deletion_lock = NULL;
+    if (ivars->snapshot_lock) {
+        Lock_Release(ivars->snapshot_lock);
+        DECREF(ivars->snapshot_lock);
+        ivars->snapshot_lock = NULL;
     }
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/go/lucy/index_test.go
----------------------------------------------------------------------
diff --git a/go/lucy/index_test.go b/go/lucy/index_test.go
index bf1ba1e..a47c364 100644
--- a/go/lucy/index_test.go
+++ b/go/lucy/index_test.go
@@ -173,14 +173,6 @@ func TestIndexManagerAccessors(t *testing.T) {
        if got := manager.getMergeLockInterval(); got != 43 {
                t.Errorf("set/getMergeLockInterval: %d", got)
        }
-       manager.setDeletionLockTimeout(71)
-       if got := manager.getDeletionLockTimeout(); got != 71 {
-               t.Errorf("set/getDeletionLockTimeout: %d", got)
-       }
-       manager.setDeletionLockInterval(41)
-       if got := manager.getDeletionLockInterval(); got != 41 {
-               t.Errorf("set/getDeletionLockInterval: %d", got)
-       }
 }
 
 func TestIndexManagerLocks(t *testing.T) {
@@ -192,11 +184,8 @@ func TestIndexManagerLocks(t *testing.T) {
        if _, ok := manager.makeMergeLock().(Lock); !ok {
                t.Errorf("makeMergeLock")
        }
-       if _, ok := manager.makeDeletionLock().(Lock); !ok {
-               t.Errorf("makeDeletionLock")
-       }
        snapFile := "snapshot_4a.json"
-       if _, ok := manager.makeSnapshotReadLock(snapFile).(Lock); !ok {
+       if _, ok := manager.makeSnapshotLock(snapFile).(Lock); !ok {
                t.Errorf("makeDeletionLock")
        }
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/perl/t/109-read_locking.t
----------------------------------------------------------------------
diff --git a/perl/t/109-read_locking.t b/perl/t/109-read_locking.t
index 6a39813..60dbc1c 100644
--- a/perl/t/109-read_locking.t
+++ b/perl/t/109-read_locking.t
@@ -17,19 +17,10 @@ use strict;
 use warnings;
 use lib 'buildlib';
 
-use Test::More tests => 15;
-
-package FastIndexManager;
-use base qw( Lucy::Index::IndexManager );
-
-sub new {
-    my $self = shift->SUPER::new(@_);
-    $self->set_deletion_lock_timeout(100);
-    return $self;
-}
+use Test::More tests => 14;
 
 package NonMergingIndexManager;
-use base qw( FastIndexManager );
+use base qw( Lucy::Index::IndexManager );
 sub recycle { [] }
 
 package main;
@@ -43,49 +34,51 @@ my $schema  = Lucy::Test::TestSchema->new;
 my $indexer = Lucy::Index::Indexer->new(
     index   => $folder,
     schema  => $schema,
-    manager => FastIndexManager->new,
+    manager => Lucy::Index::IndexManager->new,
     create  => 1,
 );
 $indexer->delete_by_term( field => 'content', term => $_ ) for qw( a b c );
 $indexer->add_doc( { content => 'x' } );
 
-# Artificially create deletion lock.
-my $outstream = $folder->open_out('locks/deletion.lock')
+# Artificially create snapshot lock.
+my $outstream = $folder->open_out('locks/snapshot_1.lock')
     or die Clownfish->error;
 $outstream->print("{}");
 $outstream->close;
-{
-    my $captured;
-    local $SIG{__WARN__} = sub { $captured = shift; };
-    $indexer->commit;
-    like( $captured, qr/obsolete/,
-        "Indexer warns if it can't get a deletion lock" );
-}
 
-ok( $folder->exists('locks/deletion.lock'),
-    "Indexer doesn't delete deletion lock when it can't get it" );
+$indexer->commit;
+
+ok( $folder->exists('locks/snapshot_1.lock'),
+    "Indexer doesn't delete snapshot lock when it can't get it" );
 my $num_ds_files = grep {m/documents\.dat$/} @{ $folder->list_r };
 cmp_ok( $num_ds_files, '>', 1,
     "Indexer doesn't process deletions when it can't get deletion lock" );
 
-my $num_snap_files = grep {m/snapshot/} @{ $folder->list_r };
+my $num_snap_files = grep {m/snapshot.*\.json/} @{ $folder->list_r };
 is( $num_snap_files, 2, "didn't zap the old snap file" );
 
 my $reader;
 SKIP: {
     skip( "IndexReader opening failure leaks", 1 )
         if $ENV{LUCY_VALGRIND};
+    my $snapshot = Lucy::Index::Snapshot->new;
+    $snapshot->read_file(
+        folder => $folder,
+        path   => 'snapshot_1.json',
+    );
     eval {
         $reader = Lucy::Index::IndexReader->open(
-            index   => $folder,
-            manager => FastIndexManager->new( host => 'me' ),
+            index    => $folder,
+            snapshot => $snapshot,
+            manager  => Lucy::Index::IndexManager->new( host => 'me' ),
         );
     };
     ok( blessed($@) && $@->isa("Lucy::Store::LockErr"),
-        "IndexReader dies if it can't get deletion lock"
+        "IndexReader dies if it can't get snapshot lock"
     );
 }
-$folder->delete('locks/deletion.lock') or die "Can't delete 'deletion.lock'";
+$folder->delete('locks/snapshot_1.lock')
+    or die "Can't delete 'snapshot_1.lock'";
 
 Test_race_condition_1: {
     my $latest_snapshot_file = latest_snapshot($folder);
@@ -103,7 +96,7 @@ Test_race_condition_1: {
 
     $reader = Lucy::Index::IndexReader->open(
         index   => $folder,
-        manager => FastIndexManager->new( host => 'me' ),
+        manager => Lucy::Index::IndexManager->new( host => 'me' ),
     );
     is( $reader->doc_count, 1,
         "reader overcomes race condition of index update after read lock" );
@@ -149,7 +142,7 @@ $folder = create_index(qw( a b c x ));
 # Establish read lock.
 $reader = Lucy::Index::IndexReader->open(
     index   => $folder,
-    manager => FastIndexManager->new( host => 'me' ),
+    manager => Lucy::Index::IndexManager->new( host => 'me' ),
 );
 
 $indexer = Lucy::Index::Indexer->new(

http://git-wip-us.apache.org/repos/asf/lucy/blob/5270b988/perl/t/111-index_manager.t
----------------------------------------------------------------------
diff --git a/perl/t/111-index_manager.t b/perl/t/111-index_manager.t
index 3cb616b..d42ae98 100644
--- a/perl/t/111-index_manager.t
+++ b/perl/t/111-index_manager.t
@@ -32,7 +32,7 @@ sub recycle {
 
 package main;
 
-use Test::More tests => 13;
+use Test::More tests => 11;
 use Lucy::Test;
 
 my $folder = Lucy::Store::RAMFolder->new;
@@ -101,11 +101,6 @@ $manager->set_merge_lock_timeout(3);
 is( $manager->get_merge_lock_timeout, 3, "set/get merge lock timeout" );
 $manager->set_merge_lock_interval(4);
 is( $manager->get_merge_lock_interval, 4, "set/get merge lock interval" );
-$manager->set_deletion_lock_timeout(5);
-is( $manager->get_deletion_lock_timeout, 5, "set/get deletion lock timeout" );
-$manager->set_deletion_lock_interval(6);
-is( $manager->get_deletion_lock_interval,
-    6, "set/get deletion lock interval" );
 
 my $indexer = Lucy::Index::Indexer->new(
     index   => $folder,

Reply via email to