Search in sources :

Example 26 with ObsoleteVersionException

use of voldemort.versioning.ObsoleteVersionException in project voldemort by voldemort.

the class InMemoryStorageEngine method put.

@Override
public synchronized void put(K key, Versioned<V> value, T transforms) throws VoldemortException {
    StoreUtils.assertValidKey(key);
    List<Versioned<V>> items = map.get(key);
    // If we have no value, add the current value
    if (items == null) {
        items = new ArrayList<Versioned<V>>();
    }
    // Check for existing versions - remember which items to
    // remove in case of success
    List<Versioned<V>> itemsToRemove = new ArrayList<Versioned<V>>(items.size());
    for (Versioned<V> versioned : items) {
        Occurred occurred = value.getVersion().compare(versioned.getVersion());
        if (occurred == Occurred.BEFORE) {
            throw new ObsoleteVersionException("Obsolete version for key '" + key + "': " + value.getVersion());
        } else if (occurred == Occurred.AFTER) {
            itemsToRemove.add(versioned);
        }
    }
    items.removeAll(itemsToRemove);
    items.add(value);
    map.put(key, items);
}
Also used : ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) Versioned(voldemort.versioning.Versioned) ArrayList(java.util.ArrayList) Occurred(voldemort.versioning.Occurred)

Example 27 with ObsoleteVersionException

use of voldemort.versioning.ObsoleteVersionException in project voldemort by voldemort.

the class ConfigurationStorageEngine method put.

@Override
public synchronized void put(String key, Versioned<String> value, String transforms) throws VoldemortException {
    StoreUtils.assertValidKey(key);
    if (null == value.getValue()) {
        throw new VoldemortException("metadata cannot be null !!");
    }
    // Check for obsolete version
    File[] files = getDirectory(key).listFiles();
    if (files != null) {
        for (File file : files) {
            if (file.getName().equals(key)) {
                VectorClock clock = readVersion(key);
                if (value.getVersion().compare(clock) == Occurred.AFTER) {
                // continue
                } else if (value.getVersion().compare(clock) == Occurred.BEFORE) {
                    throw new ObsoleteVersionException("A successor version " + clock + "  to this " + value.getVersion() + " exists for key " + key);
                } else if (value.getVersion().compare(clock) == Occurred.CONCURRENTLY) {
                    throw new ObsoleteVersionException("Concurrent Operation not allowed on Metadata.");
                }
            }
        }
    }
    File keyFile = new File(getDirectory(key), key);
    VectorClock newClock = (VectorClock) value.getVersion();
    if (!keyFile.exists() || keyFile.delete()) {
        try {
            FileUtils.writeStringToFile(keyFile, value.getValue(), "UTF-8");
            writeVersion(key, newClock);
        } catch (IOException e) {
            throw new VoldemortException(e);
        }
    }
}
Also used : ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) VectorClock(voldemort.versioning.VectorClock) IOException(java.io.IOException) VoldemortException(voldemort.VoldemortException) File(java.io.File)

Example 28 with ObsoleteVersionException

use of voldemort.versioning.ObsoleteVersionException in project voldemort by voldemort.

the class FileBackedCachingStorageEngine method put.

@Override
public /**
     * FIXME There is a problem here.. Since the versioning is on the file level, SystemStoreClient.put() 
     * will throw OVE, on the insert of the second key, value pair.Ideally, the version should be persisted 
     * along with the entries in the file too.. 
     */
void put(ByteArray key, Versioned<byte[]> value, byte[] transforms) throws VoldemortException {
    StoreUtils.assertValidKey(key);
    // Validate the Vector clock
    VectorClock clock = readVersion();
    if (clock != null) {
        if (value.getVersion().compare(clock) == Occurred.BEFORE) {
            throw new ObsoleteVersionException("A successor version " + clock + "  to this " + value.getVersion() + " exists for the current file : " + getName());
        } else if (value.getVersion().compare(clock) == Occurred.CONCURRENTLY) {
            throw new ObsoleteVersionException("Concurrent Operation not allowed on Metadata.");
        }
    }
    // Update the cache copy
    this.metadataMap.put(new String(key.get()), new String(value.getValue()));
    // Flush the data to the file
    this.flushData();
    // Persist the new Vector clock
    writeVersion((VectorClock) value.getVersion());
}
Also used : ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) VectorClock(voldemort.versioning.VectorClock)

Example 29 with ObsoleteVersionException

use of voldemort.versioning.ObsoleteVersionException in project voldemort by voldemort.

the class RedirectingStoreTest method testProxyFetchOptimizations.

@Test
public void testProxyFetchOptimizations() {
    List<ByteArray> testPrimaryKeys = new ArrayList<ByteArray>(this.proxyPutTestPrimaryEntries.keySet());
    List<ByteArray> testSecondaryKeys = new ArrayList<ByteArray>(this.proxyPutTestSecondaryEntries.keySet());
    final RedirectingStore redirectingStoreNode2 = getRedirectingStore(2, servers[2].getMetadataStore(), "test");
    final RedirectingStore redirectingStoreNode0 = getRedirectingStore(0, servers[0].getMetadataStore(), "test");
    final Store<ByteArray, byte[], byte[]> socketStoreNode2 = redirectingStoreNode2.getRedirectingSocketStore("test", 2);
    final Store<ByteArray, byte[], byte[]> socketStoreNode0 = redirectingStoreNode0.getRedirectingSocketStore("test", 0);
    long time = System.currentTimeMillis();
    // 1. Test that once a key is fetched over, get() can serve it locally..
    ByteArray primaryKey1 = testPrimaryKeys.get(1);
    assertTrue("Originally key should not exist on Node 2", socketStoreNode2.get(primaryKey1, null).size() == 0);
    assertTrue("get on Node 2 should return a valid value by proxy fetching from Node 0", redirectingStoreNode2.get(primaryKey1, null).size() > 0);
    socketStoreNode0.delete(primaryKey1, makeSuperClock(time++));
    assertTrue("Still should be able to serve it locally from Node 2", redirectingStoreNode2.get(primaryKey1, null).size() > 0);
    // 2. Test that put is still issued on top of version on remote version.
    // But once moved over, can be issued just on local version.
    ByteArray secondaryKey1 = testSecondaryKeys.get(1);
    VectorClock writeClock = makeSuperClock(time++);
    socketStoreNode0.put(secondaryKey1, new Versioned<byte[]>("value-win".getBytes(), writeClock), null);
    try {
        redirectingStoreNode2.put(secondaryKey1, new Versioned<byte[]>("value-ove".getBytes(), writeClock), null);
        fail("Missing OVE.. put should be based on remote version");
    } catch (ObsoleteVersionException ove) {
    // should have OVE if based on remote version due to equal clock
    }
    // But would have still move over value from Node 0
    assertEquals("Value not moved over from Node 0", "value-win", new String(socketStoreNode2.get(secondaryKey1, null).get(0).getValue()));
    socketStoreNode0.delete(secondaryKey1, makeSuperClock(time++));
    redirectingStoreNode2.put(secondaryKey1, new Versioned<byte[]>("value-final".getBytes(), makeSuperClock(time++)), null);
    assertEquals("Final value not found on node 2", "value-final", new String(socketStoreNode2.get(secondaryKey1, null).get(0).getValue()));
    assertEquals("Final value not found on node 0", "value-final", new String(socketStoreNode0.get(secondaryKey1, null).get(0).getValue()));
    // begin getAll() tests
    for (ByteArray key : testPrimaryKeys) {
        socketStoreNode0.delete(key, makeSuperClock(time++));
        socketStoreNode2.delete(key, makeSuperClock(time++));
        socketStoreNode0.put(key, new Versioned<byte[]>("normal".getBytes(), makeSuperClock(time++)), null);
    }
    for (ByteArray key : testSecondaryKeys) {
        socketStoreNode0.delete(key, makeSuperClock(time++));
        socketStoreNode2.delete(key, makeSuperClock(time++));
        socketStoreNode0.put(key, new Versioned<byte[]>("normal".getBytes(), makeSuperClock(time++)), null);
    }
    // 3. Test case where some keys are moved over and some are n't for
    // getAlls.
    List<ByteArray> keyList = new ArrayList<ByteArray>();
    keyList.addAll(testPrimaryKeys);
    keyList.addAll(testSecondaryKeys);
    keyList.add(new ByteArray("non-existent-key".getBytes()));
    // add the first primary & secondary key with bigger vector clock on
    // Node 2 and lower clock on Node 0..
    VectorClock smallerClock = makeSuperClock(time++);
    VectorClock biggerClock = makeSuperClock(time++);
    socketStoreNode0.put(testPrimaryKeys.get(0), new Versioned<byte[]>("loser".getBytes(), smallerClock), null);
    socketStoreNode2.put(testPrimaryKeys.get(0), new Versioned<byte[]>("winner".getBytes(), biggerClock), null);
    socketStoreNode0.put(testSecondaryKeys.get(0), new Versioned<byte[]>("loser".getBytes(), smallerClock), null);
    socketStoreNode2.put(testSecondaryKeys.get(0), new Versioned<byte[]>("winner".getBytes(), biggerClock), null);
    Map<ByteArray, List<Versioned<byte[]>>> vals = redirectingStoreNode2.getAll(keyList, null);
    assertEquals("Should contain exactly as many keys as the primary + secondary keys", testPrimaryKeys.size() + testSecondaryKeys.size(), vals.size());
    assertFalse("Should not contain non existent key", vals.containsKey(new ByteArray("non-existent-key".getBytes())));
    for (Entry<ByteArray, List<Versioned<byte[]>>> entry : vals.entrySet()) {
        String valueStr = new String(entry.getValue().get(0).getValue());
        if (entry.getKey().equals(testPrimaryKeys.get(0)) || entry.getKey().equals(testSecondaryKeys.get(0))) {
            assertEquals("Value should be 'winner'", "winner", valueStr);
        } else {
            assertEquals("Value should be 'normal'", "normal", valueStr);
        }
    }
    // Node 2
    for (ByteArray key : testPrimaryKeys) {
        socketStoreNode0.delete(key, makeSuperClock(time++));
    }
    for (ByteArray key : testSecondaryKeys) {
        socketStoreNode0.delete(key, makeSuperClock(time++));
    }
    vals = redirectingStoreNode2.getAll(keyList, null);
    assertEquals("Should contain exactly as many keys as the primary + secondary keys", testPrimaryKeys.size() + testSecondaryKeys.size(), vals.size());
    assertFalse("Should not contain non existent key", vals.containsKey(new ByteArray("non-existent-key".getBytes())));
    for (Entry<ByteArray, List<Versioned<byte[]>>> entry : vals.entrySet()) {
        String valueStr = new String(entry.getValue().get(0).getValue());
        if (entry.getKey().equals(testPrimaryKeys.get(0)) || entry.getKey().equals(testSecondaryKeys.get(0))) {
            assertEquals("Value should be 'winner'", "winner", valueStr);
        } else {
            assertEquals("Value should be 'normal'", "normal", valueStr);
        }
    }
}
Also used : VectorClock(voldemort.versioning.VectorClock) ArrayList(java.util.ArrayList) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) ByteArray(voldemort.utils.ByteArray) List(java.util.List) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Example 30 with ObsoleteVersionException

use of voldemort.versioning.ObsoleteVersionException in project voldemort by voldemort.

the class RedirectingStoreTest method testProxyGetDuringPut.

@Test
public void testProxyGetDuringPut() {
    final RedirectingStore storeNode2 = getRedirectingStore(2, servers[2].getMetadataStore(), "test");
    final RedirectingStore storeNode0 = getRedirectingStore(0, servers[0].getMetadataStore(), "test");
    // Check primary
    for (final Entry<ByteArray, byte[]> entry : primaryEntriesMoved.entrySet()) {
        try {
            // should see obsoleteVersionException for same vectorClock
            storeNode2.put(entry.getKey(), Versioned.value(entry.getValue(), new VectorClock().incremented(0, System.currentTimeMillis())), null);
            fail("Should see obsoleteVersionException here.");
        } catch (ObsoleteVersionException e) {
        // ignore
        }
        try {
            // should see obsoleteVersionException for same vectorClock
            storeNode0.put(entry.getKey(), Versioned.value(entry.getValue(), new VectorClock().incremented(0, System.currentTimeMillis())), null);
            fail("Should see obsoleteVersionException here.");
        } catch (ObsoleteVersionException e) {
        // ignore
        } catch (InvalidMetadataException e) {
        }
    }
}
Also used : ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) VectorClock(voldemort.versioning.VectorClock) InvalidMetadataException(voldemort.store.InvalidMetadataException) ByteArray(voldemort.utils.ByteArray) Test(org.junit.Test)

Aggregations

ObsoleteVersionException (voldemort.versioning.ObsoleteVersionException)43 ByteArray (voldemort.utils.ByteArray)23 VectorClock (voldemort.versioning.VectorClock)16 Versioned (voldemort.versioning.Versioned)14 Node (voldemort.cluster.Node)11 VoldemortException (voldemort.VoldemortException)10 Test (org.junit.Test)8 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)7 File (java.io.File)6 UnreachableStoreException (voldemort.store.UnreachableStoreException)6 Occurred (voldemort.versioning.Occurred)5 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 List (java.util.List)4 VoldemortConfig (voldemort.server.VoldemortConfig)4 Date (java.util.Date)3 Random (java.util.Random)3 OptionParser (joptsimple.OptionParser)3 OptionSet (joptsimple.OptionSet)3