NCache is an extremely fast and scalable Distributed Cache for .NET/.NET Core, Java, Node.js, and Python applications. NCache is used by high transaction .NET server applications for application data caching, ASP.NET / ASP.NET Core session storage, and Pub/Sub Messaging.
NCache has also become a really powerful In-Memory Distributed Datastore that is shared among multiple .NET and Java applications. As a result, applications want to store more and more types of data in NCache to be shared among multiple applications. To address this need, NCache provides Distributed Data Structures in Java and .NET to be shared across multiple users. They are:
Each of these data structures is described in more detail below.
A Distributed Queue allows you to create a Queue to be shared among multiple .NET and Java applications running in a distributed environment. And, the Queue ensures that the sequence in which you’ve entered data in it is maintained. And, all applications retrieving data from the Queue can rely on this sequence to be always correct.
string cacheName = "demoCache";
string QueueName = "DistributedQueue:Customers";
// Initialize an instance of the cache to begin performing operations:
ICache cache = NCache.Client.CacheManager.GetCache(cacheName);
// Creating a named distributed queue
IDistributedQueue<Customer> distQueue =
cache.DataTypeManager.CreateQueue<Customer>(QueueName);
distQueue.Enqueue(new Customer {
ContactName = "David Johnes",
CompanyName = "Lonesome Pine Restaurant"
});
String cacheName = "demoCache";
String queueName = "DistributedQueue:Customers";
// Initialize an instance of the cache to begin performing operations:
Cache cache = CacheManager.getCache(cacheName);
// Creating a named distributed queue
DistributedQueue<Customer> distQueue = cache.getDataStructuresManager().createQueue(queueName, Customer.class);
distQueue.add(new Customer("David Johnes", "Lonesome Pine Restaurant"));
distQueue.add(new Customer("Carlos Gonzalez", "LILA-Supermercado"));
As you can see above, a Distributed Queue allows you to add (Enqueue) items in a sequence so you can later remove (Dequeue) them in the same sequence (FIFO). Here is the Distributed Queue interface:
public interface IDistributedQueue<T> : IEnumerable<T>, IEnumerable, ICollection,
IDistributedDataTypes, ILockable, INotifiable
{
void Clear();
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
T Dequeue();
void Enqueue(T item);
T Peek();
T[] ToArray();
}
public interface DistributedQueue<T> extends Queue<T>, DistributedDataStructure, Notifiable
{
void clear();
void copyTo(T[] array, int arrayIndex);
T peek();
public interface Queue<E> extends Collection<E> {
boolean add(E e);
E remove();
}
public interface Collection<E> extends Iterable<E> {
boolean contains(Object o);
}
}
As you can see in the above-mentioned IDistributedQueue interface, it provides you with all of the traditional Queue functionality.
A Distributed HashSet behaves just like the .NET HashSet class but in a shared manner for multiple applications and users. And, a HashSet provides all Set operations like:
And, being a shared HashSet for multiple applications or users, this becomes a powerful data structure to use. Here is an example of how to use it.
string cacheName = "demoCache";
string hashSetName = "DistributedHashSet:UniqueValueHashSet";
// Initialize an instance of the cache to begin performing operations:
ICache cache = NCache.Client.CacheManager.GetCache(cacheName);
// Creating distributed HashSet with absolute expiration
IDistributedHashSet<string> hashSet;
hashSet = cache.DataTypeManager.CreateHashSet<string>(hashSetName);
// Create data for HashSet
var daysOfWeek = new string[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
// Add multiple entries to the HashSet
hashSet.AddRange(daysOfWeek);
// Since this entry already exists, no change to the HashSet is made by this call
hashSet.Add("Monday");
String cacheName = "demoCache";
String hashSetName = "DistributedHashSet:UniqueValueHashSet";
// Initialize an instance of the cache to begin performing operations:
Cache cache = CacheManager.getCache(cacheName);
// Creating distributed HashSet with absolute expiration
DistributedHashSet<String> hashSet;
hashSet = cache.getDataStructuresManager().createHashSet(hashSetName, String.class);
// Add entries to the hashset
hashSet.add("Monday");
hashSet.add("Tuesday");
hashSet.add("Wednesday");
hashSet.add("Thursday");
hashSet.add("Friday");
hashSet.add("Saturday");
hashSet.add("Sunday");
// Since this entry already exists, no change to the hashset is made by this call
hashSet.add("Monday");
As you can see, when you add “Monday” the second time, it is not added to the HashSet.
A Distributed Dictionary (IDistributedDictionary) behaves just like the regular .NET IDictionary interface but in a shared manner for multiple applications and users. And, a Distributed Dictionary provides all Dictionary operations like Add, Update, Remove, Contains, and more.
On top of regular Dictionary features, Distributed Dictionary provides the ability to expire items based on NCache expiration options like Absolute Expiration and Sliding Expiration.
ICache cache = NCache.Client.CacheManager.GetCache("demoCache");
string dictName = "DistributedDictionary:Customers";
IDistributedDictionary<string, Customer> dict = cache.DataTypeManager.GetDictionary<string, Customer>(dictName);
if (dict == null)
{
DataTypeAttributes attributes = new DataTypeAttributes {
Expiration = new Expiration(ExpirationType.Absolute, new TimeSpan(0, 1, 0))
};
// Creating distributed Dictionary with absolute expiration of 1 minute
dict = cache.DataTypeManager.CreateDictionary<string, Customer>(dictName, attributes);
}
Customer cust = new Customer
{
CustomerID = "customer1",
ContactName = "David Johnes",
CompanyName = "Lonesome Pine Restaurant",
ContactNo = "(1) 408-354-9768",
Address = "Silicon Valley, Santa Clara, California",
};
dict.Add("customer1", cust);
Customer cachedCust;
bool fetched = dict.TryGetValue("customer1", out cachedCust);
String cacheName = "demoCache";
String dictName = "DistributedDictionary:Customers";
// Initialize an instance of the cache to begin performing operations:
Cache cache = CacheManager.getCache(cacheName);
DistributedMap<string, Customer> dict = cache.getDataStructuresManager().createMap(dictName, Customer.class);
Customer customer = new Customer("David Johnes", "Lonesome Pine Restaurant", "Customer1", "(1) 408-354-9768");
dict.put("customer1", customer);
Customer cachedCustomer = dict.get("customer1");
As you can see, the Distributed Dictionary behaves just like a regular .NET Distributed (IDictionary interface). But, behind the scenes, it is distributed which makes it very scalable. And, it is also shared across multiple applications.
Distributed List behaves just like the regular .NET IList but with the difference that it is distributed and can be shared across multiple applications and processes. Distributed List is an unsorted list and you can add items either at the end of the list through the Add() method or at any location through the Insert() method by providing an index.
Below is an example of how to use a Distributed List.
ICache cache = NCache.Client.CacheManager.GetCache("demoCache");
string listName = "DistributedList:Customers";
IDistributedList<Customer> distList = cache.DataTypeManager.GetList<Customer>(listName);
if (distList == null)
{
DataTypeAttributes attributes = new DataTypeAttributes {
Expiration = new Expiration(ExpirationType.Absolute, new TimeSpan(0, 1, 0))
};
// Creating Distributed List with absolute expiration of 1 minute
distList = cache.DataTypeManager.CreateList<Customer>(listName, attributes);
}
Customer cust = new Customer
{
CustomerID = "customer1",
ContactName = "David Johnes",
CompanyName = "Lonesome Pine Restaurant",
ContactNo = "(1) 408-354-9768",
Address = "Silicon Valley, Santa Clara, California",
};
distList.Add(cust);
Customer cachedCustomer = distList[0];
String cacheName = "demoCache";
String listName = "DistributedList:Customers";
// Initialize an instance of the cache to begin performing operations:
Cache cache = CacheManager.getCache(cacheName);
DistributedList distributedList = cache.getDataStructuresManager().createList(listName, Customer.class);
Customer customer = new Customer("David Johnes", "Lonesome Pine Restaurant", "Customer1", "(1) 408-354-9768");
distributedList.add(customer);
Customer cachedCustomer = (Customer) distributedList.get(0);
You can also remove items from the list, iterate over it, and perform many other operations.
Distributed Counter is a powerful data structure in NCache that allows you to maintain a unique Counter in a distributed environment shared by multiple applications. This has a lot of uses and allows you to quickly develop applications around it. Below is an example:
ICache cache = NCache.Client.CacheManager.GetCache("demoCache");
string counterName = "DistributedCounter:Customers";
ICounter counter = cache.DataTypeManager.GetCounter(counterName);
if (counter == null)
{
DataTypeAttributes attributes = new DataTypeAttributes {
Expiration = new Expiration(ExpirationType.Absolute, new TimeSpan(0, 1, 0))
};
// Creating Distributed Counter with absolute expiration to modify cache properties of the Counter, provide an instance of DataTypeAttributes in the second parameter
counter = cache.DataTypeManager.CreateCounter(counterName, attributes);
}
counter.SetValue(1000);
long newValue = counter.IncrementBy(5);
newValue = counter.Value;
newValue = counter.DecrementBy(2);
String cacheName = "demoCache";
String counterName = "DistributedCounter:Customers";
// Initialize an instance of the cache to begin performing operations:
Cache cache = CacheManager.getCache(cacheName);
Counter counter = cache.getDataStructuresManager().createCounter(counterName);
counter.setValue(1000);
long newValue = counter.incrementBy(5);
newValue = counter.getValue();
newValue = counter.decrementBy(2);