You've already forked linux-packaging-mono
288 lines
9.1 KiB
C#
288 lines
9.1 KiB
C#
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
* (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Lucene.Net.Support;
|
|
using NUnit.Framework;
|
|
|
|
using WhitespaceAnalyzer = Lucene.Net.Analysis.WhitespaceAnalyzer;
|
|
using Document = Lucene.Net.Documents.Document;
|
|
using Field = Lucene.Net.Documents.Field;
|
|
using MaxFieldLength = Lucene.Net.Index.IndexWriter.MaxFieldLength;
|
|
using Directory = Lucene.Net.Store.Directory;
|
|
using MockRAMDirectory = Lucene.Net.Store.MockRAMDirectory;
|
|
using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
|
|
|
|
namespace Lucene.Net.Index
|
|
{
|
|
|
|
/// <summary> Test class to illustrate using IndexDeletionPolicy to provide multi-level rollback capability.
|
|
/// This test case creates an index of records 1 to 100, introducing a commit point every 10 records.
|
|
///
|
|
/// A "keep all" deletion policy is used to ensure we keep all commit points for testing purposes
|
|
/// </summary>
|
|
|
|
[TestFixture]
|
|
public class TestTransactionRollback:LuceneTestCase
|
|
{
|
|
|
|
private const System.String FIELD_RECORD_ID = "record_id";
|
|
private Directory dir;
|
|
|
|
|
|
//Rolls back index to a chosen ID
|
|
private void RollBackLast(int id)
|
|
{
|
|
|
|
// System.out.println("Attempting to rollback to "+id);
|
|
System.String ids = "-" + id;
|
|
IndexCommit last = null;
|
|
var commits = IndexReader.ListCommits(dir);
|
|
for (System.Collections.IEnumerator iterator = commits.GetEnumerator(); iterator.MoveNext(); )
|
|
{
|
|
IndexCommit commit = (IndexCommit) iterator.Current;
|
|
System.Collections.Generic.IDictionary<string, string> ud = commit.UserData;
|
|
if (ud.Count > 0)
|
|
if (((System.String) ud["index"]).EndsWith(ids))
|
|
last = commit;
|
|
}
|
|
|
|
if (last == null)
|
|
throw new System.SystemException("Couldn't find commit point " + id);
|
|
|
|
IndexWriter w = new IndexWriter(dir, new WhitespaceAnalyzer(), new RollbackDeletionPolicy(this, id), MaxFieldLength.UNLIMITED, last);
|
|
System.Collections.Generic.IDictionary<string, string> data = new System.Collections.Generic.Dictionary<string, string>();
|
|
data["index"] = "Rolled back to 1-" + id;
|
|
w.Commit(data);
|
|
w.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestRepeatedRollBacks()
|
|
{
|
|
|
|
int expectedLastRecordId = 100;
|
|
while (expectedLastRecordId > 10)
|
|
{
|
|
expectedLastRecordId -= 10;
|
|
RollBackLast(expectedLastRecordId);
|
|
|
|
System.Collections.BitArray expecteds = new System.Collections.BitArray((100 % 64 == 0?100 / 64:100 / 64 + 1) * 64);
|
|
for (int i = 1; i < (expectedLastRecordId + 1); i++) { expecteds.Set(i, true); }
|
|
CheckExpecteds(expecteds);
|
|
}
|
|
}
|
|
|
|
private void CheckExpecteds(System.Collections.BitArray expecteds)
|
|
{
|
|
IndexReader r = IndexReader.Open(dir, true);
|
|
|
|
//Perhaps not the most efficient approach but meets our needs here.
|
|
for (int i = 0; i < r.MaxDoc; i++)
|
|
{
|
|
if (!r.IsDeleted(i))
|
|
{
|
|
System.String sval = r.Document(i).Get(FIELD_RECORD_ID);
|
|
if (sval != null)
|
|
{
|
|
int val = System.Int32.Parse(sval);
|
|
Assert.IsTrue(expecteds.Get(val), "Did not expect document #" + val);
|
|
expecteds.Set(val, false);
|
|
}
|
|
}
|
|
}
|
|
r.Close();
|
|
Assert.AreEqual(0, BitSetSupport.Cardinality(expecteds), "Should have 0 docs remaining ");
|
|
}
|
|
|
|
/*
|
|
private void showAvailableCommitPoints() throws Exception {
|
|
Collection commits = IndexReader.listCommits(dir);
|
|
for (Iterator iterator = commits.iterator(); iterator.hasNext();) {
|
|
IndexCommit comm = (IndexCommit) iterator.next();
|
|
System.out.print("\t Available commit point:["+comm.getUserData()+"] files=");
|
|
Collection files = comm.getFileNames();
|
|
for (Iterator iterator2 = files.iterator(); iterator2.hasNext();) {
|
|
String filename = (String) iterator2.next();
|
|
System.out.print(filename+", ");
|
|
}
|
|
System.out.println();
|
|
}
|
|
}
|
|
*/
|
|
|
|
[SetUp]
|
|
public override void SetUp()
|
|
{
|
|
base.SetUp();
|
|
dir = new MockRAMDirectory();
|
|
|
|
//Build index, of records 1 to 100, committing after each batch of 10
|
|
IndexDeletionPolicy sdp = new KeepAllDeletionPolicy(this);
|
|
IndexWriter w = new IndexWriter(dir, new WhitespaceAnalyzer(), sdp, MaxFieldLength.UNLIMITED);
|
|
for (int currentRecordId = 1; currentRecordId <= 100; currentRecordId++)
|
|
{
|
|
Document doc = new Document();
|
|
doc.Add(new Field(FIELD_RECORD_ID, "" + currentRecordId, Field.Store.YES, Field.Index.ANALYZED));
|
|
w.AddDocument(doc);
|
|
|
|
if (currentRecordId % 10 == 0)
|
|
{
|
|
System.Collections.Generic.IDictionary<string, string> data = new System.Collections.Generic.Dictionary<string,string>();
|
|
data["index"] = "records 1-" + currentRecordId;
|
|
w.Commit(data);
|
|
}
|
|
}
|
|
|
|
w.Close();
|
|
}
|
|
|
|
// Rolls back to previous commit point
|
|
internal class RollbackDeletionPolicy : IndexDeletionPolicy
|
|
{
|
|
private void InitBlock(TestTransactionRollback enclosingInstance)
|
|
{
|
|
this.enclosingInstance = enclosingInstance;
|
|
}
|
|
private TestTransactionRollback enclosingInstance;
|
|
public TestTransactionRollback Enclosing_Instance
|
|
{
|
|
get
|
|
{
|
|
return enclosingInstance;
|
|
}
|
|
|
|
}
|
|
private int rollbackPoint;
|
|
|
|
public RollbackDeletionPolicy(TestTransactionRollback enclosingInstance, int rollbackPoint)
|
|
{
|
|
InitBlock(enclosingInstance);
|
|
this.rollbackPoint = rollbackPoint;
|
|
}
|
|
|
|
public virtual void OnCommit<T>(IList<T> commits) where T : IndexCommit
|
|
{
|
|
}
|
|
|
|
public virtual void OnInit<T>(IList<T> commits) where T : IndexCommit
|
|
{
|
|
for (System.Collections.IEnumerator iterator = commits.GetEnumerator(); iterator.MoveNext(); )
|
|
{
|
|
IndexCommit commit = (IndexCommit) iterator.Current;
|
|
System.Collections.Generic.IDictionary<string, string> userData = commit.UserData;
|
|
if (userData.Count > 0)
|
|
{
|
|
// Label for a commit point is "Records 1-30"
|
|
// This code reads the last id ("30" in this example) and deletes it
|
|
// if it is after the desired rollback point
|
|
System.String x = (System.String) userData["index"];
|
|
System.String lastVal = x.Substring(x.LastIndexOf("-") + 1);
|
|
int last = System.Int32.Parse(lastVal);
|
|
if (last > rollbackPoint)
|
|
{
|
|
/*
|
|
System.out.print("\tRolling back commit point:" +
|
|
" UserData="+commit.getUserData() +") ("+(commits.size()-1)+" commit points left) files=");
|
|
Collection files = commit.getFileNames();
|
|
for (Iterator iterator2 = files.iterator(); iterator2.hasNext();) {
|
|
System.out.print(" "+iterator2.next());
|
|
}
|
|
System.out.println();
|
|
*/
|
|
|
|
commit.Delete();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal class DeleteLastCommitPolicy : IndexDeletionPolicy
|
|
{
|
|
public DeleteLastCommitPolicy(TestTransactionRollback enclosingInstance)
|
|
{
|
|
InitBlock(enclosingInstance);
|
|
}
|
|
private void InitBlock(TestTransactionRollback enclosingInstance)
|
|
{
|
|
this.enclosingInstance = enclosingInstance;
|
|
}
|
|
private TestTransactionRollback enclosingInstance;
|
|
public TestTransactionRollback Enclosing_Instance
|
|
{
|
|
get
|
|
{
|
|
return enclosingInstance;
|
|
}
|
|
|
|
}
|
|
|
|
public virtual void OnCommit<T>(IList<T> commits) where T : IndexCommit
|
|
{
|
|
}
|
|
|
|
public virtual void OnInit<T>(IList<T> commits) where T : IndexCommit
|
|
{
|
|
commits[commits.Count - 1].Delete();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestRollbackDeletionPolicy()
|
|
{
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
// Unless you specify a prior commit point, rollback
|
|
// should not work:
|
|
new IndexWriter(dir, new WhitespaceAnalyzer(), new DeleteLastCommitPolicy(this), MaxFieldLength.UNLIMITED).Close();
|
|
IndexReader r = IndexReader.Open(dir, true);
|
|
Assert.AreEqual(100, r.NumDocs());
|
|
r.Close();
|
|
}
|
|
}
|
|
|
|
// Keeps all commit points (used to build index)
|
|
internal class KeepAllDeletionPolicy : IndexDeletionPolicy
|
|
{
|
|
public KeepAllDeletionPolicy(TestTransactionRollback enclosingInstance)
|
|
{
|
|
InitBlock(enclosingInstance);
|
|
}
|
|
private void InitBlock(TestTransactionRollback enclosingInstance)
|
|
{
|
|
this.enclosingInstance = enclosingInstance;
|
|
}
|
|
private TestTransactionRollback enclosingInstance;
|
|
public TestTransactionRollback Enclosing_Instance
|
|
{
|
|
get
|
|
{
|
|
return enclosingInstance;
|
|
}
|
|
|
|
}
|
|
public virtual void OnCommit<T>(IList<T> commits) where T : IndexCommit
|
|
{
|
|
}
|
|
public virtual void OnInit<T>(IList<T> commits) where T : IndexCommit
|
|
{
|
|
}
|
|
}
|
|
}
|
|
} |