/**File Name :           Database.java
  *
  *Authors   :           Prashanth. K
  *                      Shireen Javali
  *
  *Date      :           20/05/2000
  *
  *Function  :           Maintains a database of the search 
  *                      strings and the corresponding url's
  */                        
                         

/**The database consists of the following files: 
  *The links file contains the list of links of the sites each
  *occupying 50 bytes of space 
  *The index file contains a search string followed
  *by offsets in the links file where the strings are stored
  *
  *The data base is updated using 3 files
  *The links file , the index file & the temp file
  *
  *The temp file contains the new links to be entered
  */



import java.io.*;
import java.util.StringTokenizer;
import java.math.*;


public class Database
{
/**This method updates the database by adding a search string to it
  *It takes care not to repeat a url while updating
  */


   public void update(String indexFileName, String linksFileName,String tempFileName,String countFileName,String searchString) throws IOException
   {
      RandomAccessFile indexFile = new RandomAccessFile (indexFileName,"rw");
      RandomAccessFile linksFile = new RandomAccessFile (linksFileName,"rw");
      RandomAccessFile tempFile  = new RandomAccessFile (tempFileName ,"rw");
      RandomAccessFile countFile = new RandomAccessFile (countFileName,"rw");
      RandomAccessFile tempIndexFile = new RandomAccessFile ("tempIndex.dat","rw");
		
        String latest = new String(countFile.readLine());

        int z = 0;
        byte spaces[];
        spaces = new byte[200];
        for (int i = 0 ; i < 200 ; i++)
            spaces[i] = (byte)' ';         
		
		
        BigInteger latestIndex = new BigInteger(latest);
        BigInteger unity = new BigInteger("1");
		
		int diff;
		
		long len = linksFile.length();
		linksFile.seek(len);
		
		long lenOfTempFile = tempFile.length();
		long fpOfTempFile  = 0;
		
		long lenOfIndexFile = indexFile.length();

        long indexFilePtr = 0;
        boolean notFound = true;
        indexFile.seek(0);
        String line;

        while(notFound && (indexFilePtr < lenOfIndexFile))
        {
            line = indexFile.readLine();
         
            if(line.trim().equals(searchString.trim()))
              notFound = false;
            else
            {
               tempIndexFile.writeBytes(line+"\r\n");
               line = indexFile.readLine();
               tempIndexFile.writeBytes(line+"\r\n");
            }
            indexFilePtr = indexFile.getFilePointer();
        }
        if(!notFound)
        {
            indexFile.readLine();
            //write the remaining file
            while(indexFilePtr < lenOfIndexFile)
            {
               line = indexFile.readLine();
               tempIndexFile.writeBytes(line+"\r\n");
               indexFilePtr = indexFile.getFilePointer();
            }

        }

        tempIndexFile.writeBytes(searchString+"\r\n");

         byte buffer[] = new byte[200];

         while(fpOfTempFile < lenOfTempFile) 
         {
			try
			{
                System.out.println("here   3");
				String link = new String(tempFile.readLine());
				long fpOfLinksFile = 0;
				boolean found = false;
				linksFile.seek(0);
				long lenOfLinksFile = linksFile.length();
				while (fpOfLinksFile < lenOfLinksFile)
				{
                    linksFile.read(buffer);
                    String str = new String (buffer);

                    if (str.trim().equals(link.trim()))
					{
						found = true;
						break;
					}		
					fpOfLinksFile = linksFile.getFilePointer();
				}	
				if (found)
				{
					fpOfLinksFile = linksFile.getFilePointer();
                    Long toBeWritten = new Long(fpOfLinksFile / 200);
                    tempIndexFile.writeBytes(Long.toString(fpOfLinksFile / 200)+ "  ");
				}
				else
				{
                    System.out.println("here   4");
					linksFile.writeBytes(link);

                    System.out.println(link+"  "+link.length());

                    diff = 200 - link.length();
                    System.out.println("here 5");
					linksFile.write(spaces,0,diff);
                  //  linksFile.writeBytes("\r\n");

                    System.out.println("here 6");
                    latestIndex = latestIndex.add(unity);
                    tempIndexFile.writeBytes(latestIndex.toString()+ " "); 
				}
                System.out.println("here 7");
				fpOfTempFile = tempFile.getFilePointer() ;
                System.out.println("here     "+z++);
			}
			catch( NullPointerException e)
			{
			}
		}
		indexFile.writeBytes("\r\n");
        countFile.seek(0);
		countFile.writeBytes(latestIndex.toString());		

        countFile.close();
        linksFile.close();
		indexFile.close();
		tempFile.close();
        tempIndexFile.close();

        File iF = new File(indexFileName);
        File tiF = new File("tempIndex.dat");
        iF.delete();
        tiF.renameTo(iF);



	}

    public void deleteLinks(String token, String indexFileName,int idx[])
    {

        //modify in case of no links
        try
        {
            RandomAccessFile indexFile = new RandomAccessFile (indexFileName,"rw");
            RandomAccessFile tempIndexFile = new RandomAccessFile ("tempIndex.dat","rw");
         
            int z = 0;
            int diff;
         
         
         
            long lenOfIndexFile = indexFile.length();
            long indexFilePtr = 0;
    
            boolean notFound = true;
            indexFile.seek(0);
    
            String line;

            while(notFound && (indexFilePtr < lenOfIndexFile))
            {
                line = indexFile.readLine();
             
                if(line.trim().equals(token.trim()))
                  notFound = false;
                else
                {
                   tempIndexFile.writeBytes(line+"\r\n");
                   line = indexFile.readLine();
                   tempIndexFile.writeBytes(line+"\r\n");
                }
                indexFilePtr = indexFile.getFilePointer();
            }
            if(notFound)
            {
                indexFile.close();
                tempIndexFile.close();
        
                File iF = new File(indexFileName);
                File tiF = new File("tempIndex.dat");
                iF.delete();
                tiF.renameTo(iF);

                System.out.println("returning");

                return;
            }
    
            //if found

                StringTokenizer storeIndex = new StringTokenizer(indexFile.readLine(),"  ",false);
                indexFilePtr = indexFile.getFilePointer();

                //write the remaining file

                while(indexFilePtr < lenOfIndexFile)
                {
                   line = indexFile.readLine();
                   tempIndexFile.writeBytes(line+"\r\n");
                   indexFilePtr = indexFile.getFilePointer();
                }
    
             System.out.println("deleting links for  "+token);
             tempIndexFile.writeBytes(token+"\r\n");
    
             int idxPtr = 0;
             while(storeIndex.hasMoreTokens())
             {
                if(idxPtr < idx.length)
                {
                  if(idx[idxPtr] == idxPtr )
                   storeIndex.nextToken();
                
                else
                   tempIndexFile.writeBytes(storeIndex.nextToken()+ "  ");
                }
                else
                   tempIndexFile.writeBytes(storeIndex.nextToken()+ "  ");

                idxPtr++;
             }
             
    
    
            tempIndexFile.writeBytes("\r\n");
            indexFile.close();
            tempIndexFile.close();
    
            File iF = new File(indexFileName);
            File tiF = new File("tempIndex.dat");
            iF.delete();
            tiF.renameTo(iF);
        }
        catch(FileNotFoundException fe)
        {
        }
        catch(IOException ie)
        {
        }
         
    }

/**This method searches if a string is present in database
  *and returns the corresponding url's
  */

    public boolean search(String indexFileName,String linksFileName,String outFileName,String searchString) throws IOException
	{

        long fpOfIndexFile = 0;
        RandomAccessFile indexFile = null;
        RandomAccessFile linksFile = null;
        RandomAccessFile outFile = null;
        byte buffer[];

        long lenOfIndexFile;
        try
        {
            indexFile = new RandomAccessFile (indexFileName,"rw");
            linksFile = new RandomAccessFile (linksFileName,"rw");
            outFile = new RandomAccessFile(outFileName,"rw");

            buffer = new byte[200];
            lenOfIndexFile = indexFile.length();

            System.out.println("here   2");
            while(fpOfIndexFile < lenOfIndexFile)
            {
               System.out.println("here   3");               
               if(indexFile.readLine().trim().equals(searchString.trim()))
               {
                    

                    System.out.println("file length "+outFile.length());

                    StringTokenizer t = new StringTokenizer(indexFile.readLine(),"  ");
                    while(t.hasMoreTokens())
                    {
                      BigInteger linkIndex = new BigInteger(t.nextToken());
                      long fp = linkIndex.longValue();
                      fp = (fp-1) *200;
                      linksFile.seek(fp);
                      linksFile.read(buffer);
                      String str = new String (buffer);
                      int i = str.indexOf(" ");
                      str = str.substring(0,i);
                      System.out.println(str);
    
                      outFile.writeBytes(str+"\r\n");
                   }
                   indexFile.close();
                   linksFile.close();
                   outFile.close();
                   return true;
                }
                else
                   indexFile.readLine();

                fpOfIndexFile   = indexFile.getFilePointer();
               
    
            }//while
            indexFile.close();
            linksFile.close();
            outFile.close();
            return false;
        }
        catch(FileNotFoundException fe)
        {
            System.out.println(fe);
            return false;
        }
        catch(IOException ie)
        {
             System.out.println(ie);
             return false;
        }
        catch(NumberFormatException nfe)
        {
             System.out.println(nfe);
             return false;
        }
        catch(NullPointerException npe)
        {
             System.out.println(npe);
             fpOfIndexFile = indexFile.getFilePointer();
             return false;
        }
			
	}
}



