Package org.helidb.backend

Source Code of org.helidb.backend.AbstractVariableRecordSizeBackendTest

/* HeliDB -- A simple database for Java, http://www.helidb.org
* Copyright (C) 2008, 2009 Karl Gustafsson
*
* This file is a part of HeliDB.
*
* HeliDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeliDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.helidb.backend;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.entityfs.RandomAccess;
import org.entityfs.support.io.RandomAccessMode;
import org.entityfs.util.io.ReadWritableFileAdapter;
import org.helidb.lang.KeyExistsException;
import org.helidb.lang.Record;
import org.helidb.search.SearchMode;
import org.helidb.test.support.FileSupport;
import org.helidb.util.ComparableComparator;
import org.junit.Test;

public abstract class AbstractVariableRecordSizeBackendTest<P> extends AbstractDatabaseBackendTest<String, String, P>
{
  @Override
  protected String createKey()
  {
    return "a key";
  }

  @Override
  protected String createValue()
  {
    return "a value";
  }

  @Override
  protected void populateBackend(DatabaseBackend<String, String, P> b)
  {
    b.insert("key1", "value1");
    b.insert("key10", "value10");
  }

  @Test
  public void testInsertAndRead()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      int contentsVersion = b.getContentsVersion();
      assertEquals(0, b.getKeys().size());
      assertEquals(0, b.getValues().size());
      assertNull(b.find("key1"));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.insert("key1", "value1");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(1, b.getKeys().size());
      assertEquals(1, b.getValues().size());
      P pos = b.find("key1");
      assertNotNull(pos);
      assertRecordEquals(new Record<String, String>("key1", "value1"), b, pos);
      assertNull(b.find("key2"));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.insert("key 2", "value 2");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(2, b.getKeys().size());
      assertEquals(2, b.getValues().size());
      pos = b.find("key 2");
      assertNotNull(pos);
      assertEquals("key 2", b.readKeyAt(pos));
      assertEquals("value 2", b.readValueAt(pos));
      assertRecordEquals(new Record<String, String>("key 2", "value 2"), b, pos);
      assertEquals(contentsVersion, b.getContentsVersion());

      b.close();
      try
      {
        b.insert("key1", "value1");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }

      try
      {
        b.find("key1");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testGetKeysValuesAndRecords()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      int contentsVersion = b.getContentsVersion();
      assertEquals(0, b.getKeys().size());
      assertEquals(0, b.getValues().size());
      assertEquals(0, b.getRecords().size());
      assertEquals(contentsVersion, b.getContentsVersion());

      b.insert("key 1", "value 1");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(1, b.getKeys().size());
      assertTrue(b.getKeys().contains("key 1"));
      assertEquals(1, b.getValues().size());
      assertTrue(b.getValues().contains("value 1"));
      assertEquals(1, b.getRecords().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 1", "value 1")));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.insert("key 2", "value 2");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(2, b.getKeys().size());
      assertTrue(b.getKeys().contains("key 1"));
      assertTrue(b.getKeys().contains("key 2"));
      assertEquals(2, b.getValues().size());
      assertTrue(b.getValues().contains("value 1"));
      assertTrue(b.getValues().contains("value 2"));
      assertEquals(2, b.getRecords().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 1", "value 1")));
      assertTrue(b.getRecords().contains(new Record<String, String>("key 2", "value 2")));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.removeAt(b.find("key 1"), "key 1");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(1, b.getKeys().size());
      assertTrue(b.getKeys().contains("key 2"));
      assertEquals(1, b.getValues().size());
      assertTrue(b.getValues().contains("value 2"));
      assertEquals(1, b.getRecords().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 2", "value 2")));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.removeAt(b.find("key 2"), "key 2");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(0, b.getKeys().size());
      assertEquals(0, b.getValues().size());
      assertEquals(0, b.getRecords().size());
      assertEquals(contentsVersion, b.getContentsVersion());

      b.close();
      try
      {
        b.getKeys();
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }

      try
      {
        b.getValues();
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }

      try
      {
        b.getRecords();
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testFind()
  {
    Comparator<String> cmp = new ComparableComparator<String>();
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      assertNull(b.find("key 1"));
      b.insert("key 1", "value 1");
      int contentsVersion = b.getContentsVersion();
      assertNotNull(b.find("key 1"));
      assertNotNull(b.find("key 1", SearchMode.EXACT_MATCH, cmp));
      assertNull(b.find("key 2"));
      assertNull(b.find("key 2", SearchMode.EXACT_MATCH, cmp));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.insert("key 2", "value 2");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertNotNull(b.find("key 1"));
      assertNotNull(b.find("key 1", SearchMode.EXACT_MATCH, cmp));
      assertNotNull(b.find("key 2"));
      assertNotNull(b.find("key 2", SearchMode.EXACT_MATCH, cmp));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.removeAt(b.find("key 1"), "key 1");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertNull(b.find("key 1"));
      assertNull(b.find("key 1", SearchMode.EXACT_MATCH, cmp));
      assertNotNull(b.find("key 2"));
      assertNotNull(b.find("key 2", SearchMode.EXACT_MATCH, cmp));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.removeAt(b.find("key 2"), "key 2");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertNull(b.find("key 1"));
      assertNull(b.find("key 1", SearchMode.EXACT_MATCH, cmp));
      assertNull(b.find("key 2"));
      assertNull(b.find("key 2", SearchMode.EXACT_MATCH, cmp));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.close();
      try
      {
        b.find("key 2");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
      try
      {
        b.find("key 2", SearchMode.EXACT_MATCH, cmp);
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testDelete()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      b.insert("key 1", "value 1");
      b.insert("key 2", "value 2");
      b.insert("key 3", "value 3");
      int contentsVersion = b.getContentsVersion();

      assertTrue(b.delete("key 2"));
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(2, b.getKeys().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 1", "value 1")));
      assertTrue(b.getRecords().contains(new Record<String, String>("key 3", "value 3")));
      assertEquals(contentsVersion, b.getContentsVersion());

      assertFalse(b.delete("key 2"));
      assertEquals(contentsVersion, b.getContentsVersion());
      assertEquals(2, b.getKeys().size());

      assertTrue(b.delete("key 1"));
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(1, b.getKeys().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 3", "value 3")));

      assertTrue(b.delete("key 3"));
      assertFalse(contentsVersion == b.getContentsVersion());
      assertEquals(0, b.getKeys().size());

      b.close();
      try
      {
        b.delete("key 3");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testGetValueFor()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      int contentsVersion = b.getContentsVersion();
      assertNull(b.getValueFor("key 1"));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.insert("key 1", "value 1");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals("value 1", b.getValueFor("key 1"));
      assertNull(b.getValueFor("key 2"));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.insert("key 2", "value 2");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals("value 1", b.getValueFor("key 1"));
      assertEquals("value 2", b.getValueFor("key 2"));
      assertEquals(contentsVersion, b.getContentsVersion());

      assertTrue(b.delete("key 1"));
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertNull(b.getValueFor("key 1"));
      assertEquals("value 2", b.getValueFor("key 2"));
      assertEquals(contentsVersion, b.getContentsVersion());

      assertTrue(b.delete("key 2"));
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertNull(b.getValueFor("key 1"));
      assertNull(b.getValueFor("key 2"));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.close();
      try
      {
        b.getValueFor("key 1");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testInsertCheckKeyUnique()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      int contentsVersion = b.getContentsVersion();
      b.insertCheckKeyUnique("key 1", "value 1");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      try
      {
        b.insertCheckKeyUnique("key 1", "value 1p");
        fail();
      }
      catch (KeyExistsException e)
      {
        // ok
      }
      assertEquals(contentsVersion, b.getContentsVersion());

      b.insertCheckKeyUnique("key 2", "value 2");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      try
      {
        b.insertCheckKeyUnique("key 1", "value 1p");
        fail();
      }
      catch (KeyExistsException e)
      {
        // ok
      }
      try
      {
        b.insertCheckKeyUnique("key 2", "value 2");
        fail();
      }
      catch (KeyExistsException e)
      {
        // ok
      }
      assertEquals("value 1", b.getValueFor("key 1"));
      assertEquals("value 2", b.getValueFor("key 2"));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.close();
      try
      {
        b.insertCheckKeyUnique("key 1", "value 1");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testInsertOrUpdate()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      int contentsVersion = b.getContentsVersion();
      assertFalse(b.insertOrUpdate("key 1", "value 1"));
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();

      assertTrue(b.insertOrUpdate("key 1", "value 1p"));
      assertFalse(contentsVersion == b.getContentsVersion());

      assertEquals("value 1p", b.getValueFor("key 1"));

      b.close();
      try
      {
        b.insertOrUpdate("key 1", "value 1");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testRemove()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      b.insert("key 1", "value 1");
      b.insert("key 2", "value 2");
      b.insert("key 3", "value 3");
      int contentsVersion = b.getContentsVersion();

      assertEquals("value 2", b.remove("key 2"));
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(2, b.getKeys().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 1", "value 1")));
      assertTrue(b.getRecords().contains(new Record<String, String>("key 3", "value 3")));
      assertEquals(contentsVersion, b.getContentsVersion());

      assertNull(b.remove("key 2"));
      assertEquals(contentsVersion, b.getContentsVersion());
      assertEquals(2, b.getKeys().size());
      assertEquals(contentsVersion, b.getContentsVersion());

      assertEquals("value 1", b.remove("key 1"));
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(1, b.getKeys().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 3", "value 3")));
      assertEquals(contentsVersion, b.getContentsVersion());

      assertEquals("value 3", b.remove("key 3"));
      assertFalse(contentsVersion == b.getContentsVersion());
      assertEquals(0, b.getKeys().size());

      b.close();
      try
      {
        b.remove("key 2");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testUpdate()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      b.insert("key 1", "value 1");
      int contentsVersion = b.getContentsVersion();
      b.update("key 1", "value 1p");
      assertFalse(contentsVersion == b.getContentsVersion());
      assertEquals(1, b.getKeys().size());
      assertTrue(b.getKeys().contains("key 1"));
      assertEquals(1, b.getValues().size());
      assertTrue(b.getValues().contains("value 1p"));

      b.insert("key 2", "value 2");
      contentsVersion = b.getContentsVersion();
      b.update("key 1", "value 1pp");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(2, b.getKeys().size());
      assertTrue(b.getKeys().contains("key 2"));
      assertEquals(2, b.getValues().size());
      assertTrue(b.getValues().contains("value 1pp"));

      b.close();
      try
      {
        b.update("key 1", "value 1pp");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testUpdateAt()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      b.insert("key 1", "value 1");
      int contentsVersion = b.getContentsVersion();

      b.updateAt(b.find("key 1"), "key 1", "value 1p");
      assertFalse(contentsVersion == b.getContentsVersion());
      assertEquals(1, b.getKeys().size());
      assertTrue(b.getKeys().contains("key 1"));
      assertEquals(1, b.getValues().size());
      assertTrue(b.getValues().contains("value 1p"));

      b.insert("key 2", "value 2");
      contentsVersion = b.getContentsVersion();
      b.updateAt(b.find("key 1"), "key 1", "value 1pp");
      assertFalse(contentsVersion == b.getContentsVersion());
      assertEquals(2, b.getKeys().size());
      assertTrue(b.getKeys().contains("key 2"));
      assertEquals(2, b.getValues().size());
      assertTrue(b.getValues().contains("value 1pp"));

      b.close();
      try
      {
        b.updateAt(null, "key1", "value1");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testRemoveAt()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      b.insert("key 1", "value 1");
      b.insert("key 2", "value 2");
      b.insert("key 3", "value 3");
      int contentsVersion = b.getContentsVersion();

      b.removeAt(b.find("key 2"), "key 2");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(2, b.getKeys().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 1", "value 1")));
      assertTrue(b.getRecords().contains(new Record<String, String>("key 3", "value 3")));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.removeAt(b.find("key 1"), "key 1");
      assertFalse(contentsVersion == b.getContentsVersion());
      contentsVersion = b.getContentsVersion();
      assertEquals(1, b.getKeys().size());
      assertTrue(b.getRecords().contains(new Record<String, String>("key 3", "value 3")));
      assertEquals(contentsVersion, b.getContentsVersion());

      b.removeAt(b.find("key 3"), "key 3");
      assertFalse(contentsVersion == b.getContentsVersion());
      assertEquals(0, b.getKeys().size());

      b.close();
      try
      {
        b.removeAt(null, "key 3");
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testClear()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      b.insert("key 1", "value 1");
      b.insert("key 2", "value 2");
      b.insert("key 3", "value 3");
      int contentsVersion = b.getContentsVersion();

      b.clear();
      assertFalse(contentsVersion == b.getContentsVersion());
      assertEquals(0, b.getKeys().size());

      b.close();
      try
      {
        b.clear();
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testIterator()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      assertFalse(b.iterator().hasNext());
      try
      {
        b.iterator().next();
        fail();
      }
      catch (NoSuchElementException e)
      {
        // ok
      }

      Record<String, String> kv1 = new Record<String, String>("key 1", "value 1");
      b.insert(kv1.getKey(), kv1.getValue());
      Record<String, String> kv2 = new Record<String, String>("key 2", "value 2");
      b.insert(kv2.getKey(), kv2.getValue());
      int contentsVersion = b.getContentsVersion();

      Iterator<Record<String, String>> itr = b.iterator();
      assertTrue(itr.hasNext());
      Record<String, String> kv = itr.next();
      assertTrue(kv.equals(kv1) || kv.equals(kv2));
      assertTrue(itr.hasNext());
      kv = itr.next();
      assertTrue(kv.equals(kv1) || kv.equals(kv2));
      assertFalse(itr.hasNext());
      try
      {
        itr.next();
        fail();
      }
      catch (NoSuchElementException e)
      {
        // ok
      }
      assertEquals(contentsVersion, b.getContentsVersion());

      b.close();
      try
      {
        b.iterator();
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }

    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testKeyIterator()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      assertFalse(b.keyIterator().hasNext());
      try
      {
        b.keyIterator().next();
        fail();
      }
      catch (NoSuchElementException e)
      {
        // ok
      }

      Record<String, String> kv1 = new Record<String, String>("key 1", "value 1");
      b.insert(kv1.getKey(), kv1.getValue());
      Record<String, String> kv2 = new Record<String, String>("key 2", "value 2");
      b.insert(kv2.getKey(), kv2.getValue());
      int contentsVersion = b.getContentsVersion();

      Iterator<String> itr = b.keyIterator();
      assertTrue(itr.hasNext());
      String k = itr.next();
      assertTrue(k.equals(kv1.getKey()) || k.equals(kv2.getKey()));
      assertTrue(itr.hasNext());
      k = itr.next();
      assertTrue(k.equals(kv1.getKey()) || k.equals(kv2.getKey()));
      assertFalse(itr.hasNext());
      try
      {
        itr.next();
        fail();
      }
      catch (NoSuchElementException e)
      {
        // ok
      }
      assertEquals(contentsVersion, b.getContentsVersion());

      b.close();
      try
      {
        b.keyIterator();
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testValueIterator()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      assertFalse(b.valueIterator().hasNext());
      try
      {
        b.valueIterator().next();
        fail();
      }
      catch (NoSuchElementException e)
      {
        // ok
      }

      Record<String, String> kv1 = new Record<String, String>("key 1", "value 1");
      b.insert(kv1.getKey(), kv1.getValue());
      Record<String, String> kv2 = new Record<String, String>("key 2", "value 2");
      b.insert(kv2.getKey(), kv2.getValue());
      int contentsVersion = b.getContentsVersion();

      Iterator<String> itr = b.valueIterator();
      assertTrue(itr.hasNext());
      String v = itr.next();
      assertTrue(v.equals(kv1.getValue()) || v.equals(kv2.getValue()));
      assertTrue(itr.hasNext());
      v = itr.next();
      assertTrue(v.equals(kv1.getValue()) || v.equals(kv2.getValue()));
      assertFalse(itr.hasNext());
      try
      {
        itr.next();
        fail();
      }
      catch (NoSuchElementException e)
      {
        // ok
      }
      assertEquals(contentsVersion, b.getContentsVersion());

      b.close();
      try
      {
        b.valueIterator();
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testSameValueForTwoDifferentKeys()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      String s = "One value to rule them all";
      b.insert("key1", s);
      b.insert("key10", s);

      assertEquals(2, b.getValues().size());
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testCompact()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      b.insert("key1", "value1");
      b.insert("key10", "value10");
      b.insert("key11", "value11");
      b.insert("key100", "value100");
      b.insert("key101", "value101");
      int contentsVersion = b.getContentsVersion();

      if (b.compact())
      {
        assertFalse(contentsVersion == b.getContentsVersion());
      }
      else
      {
        assertEquals(contentsVersion, b.getContentsVersion());
      }

      assertRecordEquals(new Record<String, String>("key1", "value1"), b, b.find("key1"));
      assertRecordEquals(new Record<String, String>("key10", "value10"), b, b.find("key10"));
      assertRecordEquals(new Record<String, String>("key11", "value11"), b, b.find("key11"));
      assertRecordEquals(new Record<String, String>("key100", "value100"), b, b.find("key100"));
      assertRecordEquals(new Record<String, String>("key101", "value101"), b, b.find("key101"));

      b.removeAt(b.find("key10"), "key10");
      b.removeAt(b.find("key100"), "key100");

      assertRecordEquals(new Record<String, String>("key1", "value1"), b, b.find("key1"));
      assertNull(b.find("key10"));
      assertRecordEquals(new Record<String, String>("key11", "value11"), b, b.find("key11"));
      assertNull(b.find("key100"));
      assertRecordEquals(new Record<String, String>("key101", "value101"), b, b.find("key101"));

      contentsVersion = b.getContentsVersion();
      if (b.compact())
      {
        assertFalse(contentsVersion == b.getContentsVersion());
      }
      else
      {
        assertEquals(contentsVersion, b.getContentsVersion());
      }

      assertRecordEquals(new Record<String, String>("key1", "value1"), b, b.find("key1"));
      assertNull(b.find("key10"));
      assertRecordEquals(new Record<String, String>("key11", "value11"), b, b.find("key11"));
      assertNull(b.find("key100"));
      assertRecordEquals(new Record<String, String>("key101", "value101"), b, b.find("key101"));

      b.removeAt(b.find("key1"), "key1");

      assertNull(b.find("key1"));
      assertNull(b.find("key10"));
      assertRecordEquals(new Record<String, String>("key11", "value11"), b, b.find("key11"));
      assertNull(b.find("key100"));
      assertRecordEquals(new Record<String, String>("key101", "value101"), b, b.find("key101"));

      contentsVersion = b.getContentsVersion();
      if (b.compact())
      {
        assertFalse(contentsVersion == b.getContentsVersion());
      }
      else
      {
        assertEquals(contentsVersion, b.getContentsVersion());
      }

      assertNull(b.find("key1"));
      assertNull(b.find("key10"));
      assertRecordEquals(new Record<String, String>("key11", "value11"), b, b.find("key11"));
      assertNull(b.find("key100"));
      assertRecordEquals(new Record<String, String>("key101", "value101"), b, b.find("key101"));
      assertEquals(2, b.getKeys().size());

      b.removeAt(b.find("key11"), "key11");
      b.removeAt(b.find("key101"), "key101");

      assertNull(b.find("key1"));
      assertNull(b.find("key10"));
      assertNull(b.find("key11"));
      assertNull(b.find("key100"));
      assertNull(b.find("key101"));

      contentsVersion = b.getContentsVersion();
      if (b.compact())
      {
        assertFalse(contentsVersion == b.getContentsVersion());
      }
      else
      {
        assertEquals(contentsVersion, b.getContentsVersion());
      }

      assertNull(b.find("key1"));
      assertNull(b.find("key10"));
      assertNull(b.find("key11"));
      assertNull(b.find("key100"));
      assertNull(b.find("key101"));

      b.insert("key1", "value1p");
      b.insert("key10", "value10p");

      assertRecordEquals(new Record<String, String>("key1", "value1p"), b, b.find("key1"));
      assertRecordEquals(new Record<String, String>("key10", "value10p"), b, b.find("key10"));

      contentsVersion = b.getContentsVersion();
      if (b.compact())
      {
        assertFalse(contentsVersion == b.getContentsVersion());
      }
      else
      {
        assertEquals(contentsVersion, b.getContentsVersion());
      }

      assertRecordEquals(new Record<String, String>("key1", "value1p"), b, b.find("key1"));
      assertRecordEquals(new Record<String, String>("key10", "value10p"), b, b.find("key10"));

      b.close();
      try
      {
        b.compact();
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testForEachKey()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      Collection<Record<String, P>> c = new ArrayList<Record<String, P>>(5);
      c.add(new Record<String, P>("key1", b.insert("key1", "value1")));
      c.add(new Record<String, P>("key10", b.insert("key10", "value10")));
      c.add(new Record<String, P>("key11", b.insert("key11", "value11")));
      c.add(new Record<String, P>("key100", b.insert("key100", "value100")));
      c.add(new Record<String, P>("key101", b.insert("key101", "value101")));

      TestForEachKeyCallback<String, P> cbk = new TestForEachKeyCallback<String, P>(new ArrayList<Record<String, P>>(c));

      b.forEachKey(cbk);

      assertTrue(cbk.getRemainingKeys().isEmpty());

      P k11pos = b.find("key11");
      b.removeAt(k11pos, "key11");

      c = new ArrayList<Record<String, P>>(4);
      c.add(new Record<String, P>("key1", b.find("key1")));
      c.add(new Record<String, P>("key10", b.find("key10")));
      c.add(new Record<String, P>("key100", b.find("key100")));
      c.add(new Record<String, P>("key101", b.find("key101")));

      cbk = new TestForEachKeyCallback<String, P>(new ArrayList<Record<String, P>>(c));

      b.forEachKey(cbk);

      assertTrue(cbk.getRemainingKeys().isEmpty());

      b.close();
      try
      {
        b.forEachKey(cbk);
        fail();
      }
      catch (IllegalStateException e)
      {
        // ok
      }
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testReplaceContentsWith()
  {
    DatabaseBackend<String, String, P> b1 = createBackend();
    try
    {
      b1.insert("b1 key 1", "b1 value 1");
      b1.insert("b1 key 2", "b1 value 2");
      b1.insert("b1 åäö key 3", "b1 value 3 åäö");

      DatabaseBackend<String, String, P> b2 = createBackend();
      try
      {
        b2.insert("b2 key 1", "b2 value 1");
        b2.insert("b2 key 2", "b2 value 2");

        File f = FileSupport.createTempFile();
        try
        {
          RandomAccess ra = new ReadWritableFileAdapter(f).openForRandomAccess(RandomAccessMode.READ_WRITE);
          try
          {
            long dataSize = b1.writeContentsTo(ra);
            ra.seek(0);
            int contentsVersion = b2.getContentsVersion();
            b2.replaceContentsWith(ra, dataSize);
            assertFalse(contentsVersion == b2.getContentsVersion());

            assertEquals(3, b2.getKeys().size());
            assertRecordEquals(new Record<String, String>("b1 key 1", "b1 value 1"), b2, b2.find("b1 key 1"));
            assertRecordEquals(new Record<String, String>("b1 key 2", "b1 value 2"), b2, b2.find("b1 key 2"));
            assertRecordEquals(new Record<String, String>("b1 åäö key 3", "b1 value 3 åäö"), b2, b2.find("b1 åäö key 3"));
          }
          finally
          {
            ra.close();
          }
        }
        finally
        {
          assertTrue(f.delete());
        }
      }
      finally
      {
        tearDownBackend(b2);
      }
    }
    finally
    {
      tearDownBackend(b1);
    }
  }

  @Test
  public void testFindClosestNaturalOrdering()
  {
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      assertNull(b.find("a", SearchMode.CLOSEST_BELOW));
      assertNull(b.find("a", SearchMode.CLOSEST_ABOVE));
      assertNull(b.find("a", SearchMode.CLOSEST_MATCH));

      b.insert("b", "b");
      b.insert("g", "g");
      b.insert("k", "k");
      int contentsVersion = b.getContentsVersion();

      assertNull(b.find("a", SearchMode.CLOSEST_BELOW));
      assertEquals("b", b.readKeyAt(b.find("a", SearchMode.CLOSEST_ABOVE)));
      assertEquals("b", b.readKeyAt(b.find("a", SearchMode.CLOSEST_MATCH)));

      assertEquals("b", b.readKeyAt(b.find("b", SearchMode.CLOSEST_BELOW)));
      assertEquals("b", b.readKeyAt(b.find("b", SearchMode.CLOSEST_ABOVE)));
      assertEquals("b", b.readKeyAt(b.find("b", SearchMode.CLOSEST_MATCH)));

      assertEquals("b", b.readKeyAt(b.find("c", SearchMode.CLOSEST_BELOW)));
      assertEquals("g", b.readKeyAt(b.find("c", SearchMode.CLOSEST_ABOVE)));
      assertEquals("b", b.readKeyAt(b.find("c", SearchMode.CLOSEST_MATCH)));

      assertEquals("b", b.readKeyAt(b.find("cc", SearchMode.CLOSEST_BELOW)));
      assertEquals("g", b.readKeyAt(b.find("cc", SearchMode.CLOSEST_ABOVE)));
      assertEquals("b", b.readKeyAt(b.find("cc", SearchMode.CLOSEST_MATCH)));

      assertEquals("b", b.readKeyAt(b.find("d", SearchMode.CLOSEST_BELOW)));
      assertEquals("g", b.readKeyAt(b.find("d", SearchMode.CLOSEST_ABOVE)));
      assertEquals("b", b.readKeyAt(b.find("d", SearchMode.CLOSEST_MATCH)));

      assertEquals("b", b.readKeyAt(b.find("e", SearchMode.CLOSEST_BELOW)));
      assertEquals("g", b.readKeyAt(b.find("e", SearchMode.CLOSEST_ABOVE)));
      assertEquals("g", b.readKeyAt(b.find("e", SearchMode.CLOSEST_MATCH)));

      assertEquals("b", b.readKeyAt(b.find("f", SearchMode.CLOSEST_BELOW)));
      assertEquals("g", b.readKeyAt(b.find("f", SearchMode.CLOSEST_ABOVE)));
      assertEquals("g", b.readKeyAt(b.find("f", SearchMode.CLOSEST_MATCH)));

      assertEquals("g", b.readKeyAt(b.find("g", SearchMode.CLOSEST_BELOW)));
      assertEquals("g", b.readKeyAt(b.find("g", SearchMode.CLOSEST_ABOVE)));
      assertEquals("g", b.readKeyAt(b.find("g", SearchMode.CLOSEST_MATCH)));

      assertEquals("g", b.readKeyAt(b.find("h", SearchMode.CLOSEST_BELOW)));
      assertEquals("k", b.readKeyAt(b.find("h", SearchMode.CLOSEST_ABOVE)));
      assertEquals("g", b.readKeyAt(b.find("h", SearchMode.CLOSEST_MATCH)));

      assertEquals("g", b.readKeyAt(b.find("i", SearchMode.CLOSEST_BELOW)));
      assertEquals("k", b.readKeyAt(b.find("i", SearchMode.CLOSEST_ABOVE)));
      String closestMatch = b.readKeyAt(b.find("i", SearchMode.CLOSEST_MATCH));
      assertTrue("g".equals(closestMatch) || "k".equals(closestMatch));

      assertEquals("g", b.readKeyAt(b.find("j", SearchMode.CLOSEST_BELOW)));
      assertEquals("k", b.readKeyAt(b.find("j", SearchMode.CLOSEST_ABOVE)));
      assertEquals("k", b.readKeyAt(b.find("j", SearchMode.CLOSEST_MATCH)));

      assertEquals("k", b.readKeyAt(b.find("k", SearchMode.CLOSEST_BELOW)));
      assertEquals("k", b.readKeyAt(b.find("k", SearchMode.CLOSEST_ABOVE)));
      assertEquals("k", b.readKeyAt(b.find("k", SearchMode.CLOSEST_MATCH)));

      assertEquals("k", b.readKeyAt(b.find("l", SearchMode.CLOSEST_BELOW)));
      assertNull(b.find("l", SearchMode.CLOSEST_ABOVE));
      assertEquals("k", b.readKeyAt(b.find("l", SearchMode.CLOSEST_MATCH)));

      assertEquals(contentsVersion, b.getContentsVersion());
    }
    finally
    {
      tearDownBackend(b);
    }
  }

  @Test
  public void testFindClosestCustomComparator()
  {
    Comparator<String> cmp = new ComparableComparator<String>();
    DatabaseBackend<String, String, P> b = createBackend();
    try
    {
      assertNull(b.find("a", SearchMode.CLOSEST_BELOW, cmp));
      assertNull(b.find("a", SearchMode.CLOSEST_ABOVE, cmp));
      assertNull(b.find("a", SearchMode.CLOSEST_MATCH, cmp));

      b.insert("b", "b");
      b.insert("g", "g");
      b.insert("k", "k");
      int contentsVersion = b.getContentsVersion();

      assertNull(b.find("a", SearchMode.CLOSEST_BELOW, cmp));
      assertEquals("b", b.readKeyAt(b.find("a", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("b", b.readKeyAt(b.find("a", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("b", b.readKeyAt(b.find("b", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("b", b.readKeyAt(b.find("b", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("b", b.readKeyAt(b.find("b", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("b", b.readKeyAt(b.find("c", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("g", b.readKeyAt(b.find("c", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("b", b.readKeyAt(b.find("c", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("b", b.readKeyAt(b.find("cc", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("g", b.readKeyAt(b.find("cc", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("b", b.readKeyAt(b.find("cc", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("b", b.readKeyAt(b.find("d", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("g", b.readKeyAt(b.find("d", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("b", b.readKeyAt(b.find("d", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("b", b.readKeyAt(b.find("e", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("g", b.readKeyAt(b.find("e", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("g", b.readKeyAt(b.find("e", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("b", b.readKeyAt(b.find("f", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("g", b.readKeyAt(b.find("f", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("g", b.readKeyAt(b.find("f", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("g", b.readKeyAt(b.find("g", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("g", b.readKeyAt(b.find("g", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("g", b.readKeyAt(b.find("g", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("g", b.readKeyAt(b.find("h", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("k", b.readKeyAt(b.find("h", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("g", b.readKeyAt(b.find("h", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("g", b.readKeyAt(b.find("i", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("k", b.readKeyAt(b.find("i", SearchMode.CLOSEST_ABOVE, cmp)));
      String closestMatch = b.readKeyAt(b.find("i", SearchMode.CLOSEST_MATCH, cmp));
      assertTrue("g".equals(closestMatch) || "k".equals(closestMatch));

      assertEquals("g", b.readKeyAt(b.find("j", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("k", b.readKeyAt(b.find("j", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("k", b.readKeyAt(b.find("j", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("k", b.readKeyAt(b.find("k", SearchMode.CLOSEST_BELOW, cmp)));
      assertEquals("k", b.readKeyAt(b.find("k", SearchMode.CLOSEST_ABOVE, cmp)));
      assertEquals("k", b.readKeyAt(b.find("k", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals("k", b.readKeyAt(b.find("l", SearchMode.CLOSEST_BELOW, cmp)));
      assertNull(b.find("l", SearchMode.CLOSEST_ABOVE, cmp));
      assertEquals("k", b.readKeyAt(b.find("l", SearchMode.CLOSEST_MATCH, cmp)));

      assertEquals(contentsVersion, b.getContentsVersion());
    }
    finally
    {
      tearDownBackend(b);
    }
  }
}
TOP

Related Classes of org.helidb.backend.AbstractVariableRecordSizeBackendTest

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.