The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
parcel KinoSearch cnick Kino;

/** Policies governing index updating, locking, and file deletion. 
 * 
 * IndexManager is an advanced-use class for controlling index locking,
 * updating, merging, and deletion behaviors.
 *
 * IndexManager and L<Architecture|KinoSearch::Plan::Architecture> are
 * complementary classes: Architecture is used to define traits and behaviors
 * which cannot change for the life of an index; IndexManager is used for
 * defining rules which may change from process to process.
 */
class KinoSearch::Index::IndexManager cnick IxManager 
    inherits KinoSearch::Object::Obj {

    Folder      *folder;
    CharBuf     *host;
    LockFactory *lock_factory;
    uint32_t     write_lock_timeout;
    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;

    public inert incremented IndexManager*
    new(const CharBuf *host = NULL, LockFactory *lock_factory = NULL);

    /**
     * @param host An identifier which should be unique per-machine.
     * @param lock_factory A LockFactory.
     */
    public inert IndexManager*
    init(IndexManager *self, const CharBuf *host = NULL, 
         LockFactory *lock_factory = NULL);

    public void
    Destroy(IndexManager *self);

    /**
     * Setter for <code>folder</code> member.  Typical clients (Indexer,
     * IndexReader) will use this method to install their own Folder instance.
     */
    public void
    Set_Folder(IndexManager *self, Folder *folder = NULL);

    /** Getter for <code>folder</code> member.
     */
    public nullable Folder* 
    Get_Folder(IndexManager *self);

    /** Getter for <code>host</code> member.
     */
    public CharBuf* 
    Get_Host(IndexManager *self);

    /** Return an array of SegReaders representing segments that should be
     * consolidated.  Implementations must balance index-time churn against
     * search-time degradation due to segment proliferation. The default
     * implementation prefers small segments or segments with a high
     * proportion of deletions.
     * 
     * @param reader A PolyReader.
     * @param del_writer A DeletionsWriter.
     * @param cutoff A segment number which all returned SegReaders must
     * exceed.
     * @param optimize A boolean indicating whether to spend extra time
     * optimizing the index for search-time performance.
     */
    public incremented VArray*
    Recycle(IndexManager *self, PolyReader *reader, 
            DeletionsWriter *del_writer, int64_t cutoff, 
            bool_t optimize = false);

    /** Return a tick.  All segments below that tick will be merged.
     * Exposed for testing purposes only.
     *
     * @param doc_counts Segment doc counts, in ascending order.
     */
    uint32_t
    Choose_Sparse(IndexManager *self, I32Array *doc_counts);

    /** Create the Lock which controls access to modifying the logical content
     * of the index. 
     */
    public 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.
     */
    public incremented Lock*
    Make_Deletion_Lock(IndexManager *self);

    public incremented Lock*
    Make_Merge_Lock(IndexManager *self);

    /** Write supplied data to "merge.json".  Throw an exception if the write
     * fails.
     */
    public void
    Write_Merge_Data(IndexManager *self, int64_t cutoff);

    /** Look for the "merge.json" file dropped by BackgroundMerger.  If it's
     * not there, return NULL.  If it's there but can't be decoded, return an
     * empty Hash.  If successfully decoded, return contents.
     */
    public incremented Hash*
    Read_Merge_Data(IndexManager *self);

    public bool_t
    Remove_Merge_Data(IndexManager *self);

    /** Create a shared lock on a snapshot file, which serves as a proxy for
     * all the files it lists and indicates that they must not be deleted.
     */
    public incremented Lock*
    Make_Snapshot_Read_Lock(IndexManager *self, const CharBuf *filename);

    /** Return the highest number for a segment directory which contains a
     * segmeta file in the snapshot.
     */
    public int64_t
    Highest_Seg_Num(IndexManager *self, Snapshot *snapshot);

    /** Return the name of a new snapshot file, which shall contain a base-36
     * "generation" embedded inside it greater than the generation of any
     * snapshot file currently in the index folder.
     */
    public incremented CharBuf*
    Make_Snapshot_Filename(IndexManager *self);

    /** Setter for write lock timeout.  Default: 1000 milliseconds.
     */
    public void
    Set_Write_Lock_Timeout(IndexManager *self, uint32_t timeout);

    /** Getter for write lock timeout. 
     */
    public uint32_t
    Get_Write_Lock_Timeout(IndexManager *self);

    /** Setter for write lock retry interval.  Default: 100 milliseconds.
     */
    public void
    Set_Write_Lock_Interval(IndexManager *self, uint32_t timeout);

    /** Getter for write lock retry interval. 
     */
    public uint32_t
    Get_Write_Lock_Interval(IndexManager *self);

    /** Setter for merge lock timeout.  Default: 0 milliseconds (no retries).
     */
    public void
    Set_Merge_Lock_Timeout(IndexManager *self, uint32_t timeout);

    /** Getter for merge lock timeout. 
     */
    public uint32_t
    Get_Merge_Lock_Timeout(IndexManager *self);

    /** Setter for merge lock retry interval.  Default: 1000 milliseconds.
     */
    public void
    Set_Merge_Lock_Interval(IndexManager *self, uint32_t timeout);

    /** Getter for merge lock retry interval. 
     */
    public uint32_t
    Get_Merge_Lock_Interval(IndexManager *self);

    /** Setter for deletion lock timeout.  Default: 1000 milliseconds.
     */
    public void
    Set_Deletion_Lock_Timeout(IndexManager *self, uint32_t timeout);

    /** Getter for deletion lock timeout. 
     */
    public uint32_t
    Get_Deletion_Lock_Timeout(IndexManager *self);

    /** Setter for deletion lock retry interval.  Default: 100 milliseconds.
     */
    public void
    Set_Deletion_Lock_Interval(IndexManager *self, uint32_t timeout);

    /** Getter for deletion lock retry interval. 
     */
    public uint32_t
    Get_Deletion_Lock_Interval(IndexManager *self);
}

/* Copyright 2007-2011 Marvin Humphrey
 *
 * This program is free software; you can redistribute it and/or modify
 * under the same terms as Perl itself.
 */