Cache Operations

Apache Ignite .NET data grid provides a very easy to use, yet very powerful API for data access.

With Apache Ignite .NET cache you get the following:

  • Basic Cache Operations
  • ConcurrentMap APIs
  • Collocated Processing (EntryProcessor)
  • Events and Metrics
  • Pluggable Persistence
  • ACID transactions
  • data querying capabilities (including SQL)

ICache

You can get an instance of ICache<,> directly from Ignite:

IIgnite ignite = Ignition.Start();

ICache<int, string> cache = ignite.GetCache<int, string>("mycache");

Generic cache provides a strongly-typed and high-performance way of working with data.

Note that generic arguments do not affect internal cache representation. You can work with the same cache using any generic arguments. An attempt to retrieve an entry of incompatible type will result in InvalidCastException.

Basic Operations

Here are some basic atomic operation examples.

using (var ignite = Ignition.Start())
{
    var cache = ignite.GetOrCreateCache<int, string>("myCache");

    // Store keys in cache (values will end up on different cache nodes).
    for (int i = 0; i < 10; i++)
        cache.Put(i, i.ToString());

    for (int i = 0; i < 10; i++)
        Console.WriteLine("Got [key={0}, val={1}]", i, cache.Get(i));
}
// Put-if-absent which returns previous value.
CacheResult<string> oldVal = cache.GetAndPutIfAbsent(11, "Hello");

// Put-if-absent which returns boolean success flag.
bool success = cache.PutIfAbsent(22, "World");

// Replace-if-exists operation (opposite of getAndPutIfAbsent), returns previous value.
oldVal = cache.GetAndReplace(11, "Hello");

// Replace-if-exists operation (opposite of putIfAbsent), returns boolean success flag.
success = cache.Replace(22, "World");

// Replace-if-matches operation.
success = cache.Replace(22, "World", "World!");

// Remove-if-matches operation.
success = cache.Remove(1, "Hello");

ICacheEntryProcessor

Whenever doing puts and updates in cache, you are usually sending full state object state across the network. ICacheEntryProcessor allows for processing data directly on primary nodes, often transferring only the deltas instead of the full state.

Moreover, you can embed your own logic into ICacheEntryProcessor, for example, taking previous cached value and incrementing it by specified argument.

void CacheInvoke()
{
    var ignite = Ignition.Start();

    var cache = ignite.GetOrCreateCache<int, int>("myCache");

    var proc = new Processor();

    // Increment cache value 10 times
    for (int i = 0; i < 10; i++)
        cache.Invoke(1, proc, 5);
}

class Processor : ICacheEntryProcessor<int, int, int, int>
{
    public int Process(IMutableCacheEntry<int, int> entry, int arg)
    {
        entry.Value = entry.Exists ? arg : entry.Value + arg;

        return entry.Value;
    }
}

📘

Atomicity

EntryProcessors are executed atomically within a lock on the given cache key.

Asynchronous Support

Just like all distributed APIs in Ignite, ICache supports Task-based Asynchronous Pattern and has Async counterparts of all distributed methods.

// Start asynchronous operation and obtain a Task that represents it
Task<CacheResult<string>> asyncVal = cache.GetAndPutAsync(1, "1");

// Synchronously wait for the task to complete and obtain result
Console.WriteLine(asyncVal.Result.Success);

// Use C# 5 await keyword
Console.WriteLine((await asyncVal).Success);

// Use continuation
asyncVal.ContinueWith(task => Console.WriteLine(task.Result.Success));