Package org.apache.lucene.store

Source Code of org.apache.lucene.store.TestBufferedIndexInput

package org.apache.lucene.store;

/**
* 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.
*/

import java.io.IOException;
import java.io.File;
import java.util.List;
import java.util.Random;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util._TestUtil;

import junit.framework.TestCase;

public class TestBufferedIndexInput extends TestCase {
  // Call readByte() repeatedly, past the buffer boundary, and see that it
  // is working as expected.
  // Our input comes from a dynamically generated/ "file" - see
  // MyBufferedIndexInput below.
    public void testReadByte() throws Exception {
      MyBufferedIndexInput input = new MyBufferedIndexInput();
      for(int i=0; i<BufferedIndexInput.BUFFER_SIZE*10; i++){
         assertEquals(input.readByte(), byten(i));
      }
    }
  // Call readBytes() repeatedly, with various chunk sizes (from 1 byte to
    // larger than the buffer size), and see that it returns the bytes we expect.
  // Our input comes from a dynamically generated "file" -
    // see MyBufferedIndexInput below.
    public void testReadBytes() throws Exception {
      MyBufferedIndexInput input = new MyBufferedIndexInput();
      int pos=0;
      // gradually increasing size:
      for(int size=1; size<BufferedIndexInput.BUFFER_SIZE*10; size=size+size/200+1){
        checkReadBytes(input, size, pos);
        pos+=size;
      }
      // wildly fluctuating size:
      for(long i=0; i<1000; i++){
        // The following function generates a fluctuating (but repeatable)
        // size, sometimes small (<100) but sometimes large (>10000)
        int size1 = (int)( i%7 + 7*(i%5)+ 7*5*(i%3) + 5*5*3*(i%2));
        int size2 = (int)( i%11 + 11*(i%7)+ 11*7*(i%5) + 11*7*5*(i%3) + 11*7*5*3*(i%2) );
        int size = (i%3==0)?size2*10:size1;
        checkReadBytes(input, size, pos);
        pos+=size;
      }
      // constant small size (7 bytes):
      for(int i=0; i<BufferedIndexInput.BUFFER_SIZE; i++){
        checkReadBytes(input, 7, pos);
        pos+=7;
      }
    }
   private void checkReadBytes(BufferedIndexInput input, int size, int pos) throws IOException{
     // Just to see that "offset" is treated properly in readBytes(), we
     // add an arbitrary offset at the beginning of the array
     int offset = size % 10; // arbitrary
     byte[] b = new byte[offset+size];
     input.readBytes(b, offset, size);
     for(int i=0; i<size; i++){
       assertEquals(b[offset+i], byten(pos+i));
     }
   }
  
   // This tests that attempts to readBytes() past an EOF will fail, while
   // reads up to the EOF will succeed. The EOF is determined by the
   // BufferedIndexInput's arbitrary length() value.
   public void testEOF() throws Exception {
     MyBufferedIndexInput input = new MyBufferedIndexInput(1024);
     // see that we can read all the bytes at one go:
     checkReadBytes(input, (int)input.length(), 0)
     // go back and see that we can't read more than that, for small and
     // large overflows:
     int pos = (int)input.length()-10;
     input.seek(pos);
     checkReadBytes(input, 10, pos)
     input.seek(pos);
     try {
       checkReadBytes(input, 11, pos);
           fail("Block read past end of file");
       } catch (IOException e) {
           /* success */
       }
     input.seek(pos);
     try {
       checkReadBytes(input, 50, pos);
           fail("Block read past end of file");
       } catch (IOException e) {
           /* success */
       }
     input.seek(pos);
     try {
       checkReadBytes(input, 100000, pos);
           fail("Block read past end of file");
       } catch (IOException e) {
           /* success */
       }
  }

    // byten emulates a file - byten(n) returns the n'th byte in that file.
    // MyBufferedIndexInput reads this "file".
    private static byte byten(long n){
      return (byte)(n*n%256);
    }
    private static class MyBufferedIndexInput extends BufferedIndexInput {
      private long pos;
      private long len;
      public MyBufferedIndexInput(long len){
        this.len = len;
        this.pos = 0;
      }
      public MyBufferedIndexInput(){
        // an infinite file
        this(Long.MAX_VALUE);
      }
    protected void readInternal(byte[] b, int offset, int length) throws IOException {
      for(int i=offset; i<offset+length; i++)
        b[i] = byten(pos++);
    }

    protected void seekInternal(long pos) throws IOException {
      this.pos = pos;
    }

    public void close() throws IOException {
    }

    public long length() {
      return len;
    }
    }

    public void testSetBufferSize() throws IOException {
      File indexDir = new File(System.getProperty("tempDir"), "testSetBufferSize");
      MockFSDirectory dir = new MockFSDirectory(indexDir);
      try {
        IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true);
        writer.setUseCompoundFile(false);
        for(int i=0;i<37;i++) {
          Document doc = new Document();
          doc.add(new Field("content", "aaa bbb ccc ddd" + i, Field.Store.YES, Field.Index.TOKENIZED));
          doc.add(new Field("id", "" + i, Field.Store.YES, Field.Index.TOKENIZED));
          writer.addDocument(doc);
        }
        writer.close();

        dir.allIndexInputs.clear();

        IndexReader reader = IndexReader.open(dir);
        Term aaa = new Term("content", "aaa");
        Term bbb = new Term("content", "bbb");
        Term ccc = new Term("content", "ccc");
        assertEquals(reader.docFreq(ccc), 37);
        reader.deleteDocument(0);
        assertEquals(reader.docFreq(aaa), 37);
        dir.tweakBufferSizes();
        reader.deleteDocument(4);
        assertEquals(reader.docFreq(bbb), 37);
        dir.tweakBufferSizes();

        IndexSearcher searcher = new IndexSearcher(reader);
        Hits hits = searcher.search(new TermQuery(bbb));
        dir.tweakBufferSizes();
        assertEquals(35, hits.length());
        dir.tweakBufferSizes();
        hits = searcher.search(new TermQuery(new Term("id", "33")));
        dir.tweakBufferSizes();
        assertEquals(1, hits.length());
        hits = searcher.search(new TermQuery(aaa));
        dir.tweakBufferSizes();
        assertEquals(35, hits.length());
        searcher.close();
        reader.close();
      } finally {
        _TestUtil.rmDir(indexDir);
      }
    }

    private static class MockFSDirectory extends Directory {

      List allIndexInputs = new ArrayList();

      Random rand = new Random();

      private Directory dir;

      public MockFSDirectory(File path) throws IOException {
        lockFactory = new NoLockFactory();
        dir = FSDirectory.getDirectory(path);
      }

      public IndexInput openInput(String name) throws IOException {
        return openInput(name, BufferedIndexInput.BUFFER_SIZE);
      }

      public void tweakBufferSizes() {
        Iterator it = allIndexInputs.iterator();
        int count = 0;
        while(it.hasNext()) {
          BufferedIndexInput bii = (BufferedIndexInput) it.next();
          int bufferSize = 1024+(int) Math.abs(rand.nextInt() % 32768);
          bii.setBufferSize(bufferSize);
          count++;
        }
        //System.out.println("tweak'd " + count + " buffer sizes");
      }
     
      public IndexInput openInput(String name, int bufferSize) throws IOException {
        // Make random changes to buffer size
        bufferSize = 1+(int) Math.abs(rand.nextInt() % 10);
        IndexInput f = dir.openInput(name, bufferSize);
        allIndexInputs.add(f);
        return f;
      }

      public IndexOutput createOutput(String name) throws IOException {
        return dir.createOutput(name);
      }

      public void close() throws IOException {
        dir.close();
      }

      public void deleteFile(String name)
        throws IOException
      {
        dir.deleteFile(name);
      }
      public void touchFile(String name)
        throws IOException
      {
        dir.touchFile(name);
      }
      public long fileModified(String name)
        throws IOException
      {
        return dir.fileModified(name);
      }
      public boolean fileExists(String name)
        throws IOException
      {
        return dir.fileExists(name);
      }
      public String[] list()
        throws IOException
      {
        return dir.list();
      }

      public long fileLength(String name) throws IOException {
        return dir.fileLength(name);
      }
      public void renameFile(String from, String to)
        throws IOException
      {
        dir.renameFile(from, to);
      }


    }
}
TOP

Related Classes of org.apache.lucene.store.TestBufferedIndexInput

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.