Architectural Patterns for Scalability

In today’s computing one of the biggest challenge is scalability to deal with high volume traffics, big data and processes.

There are several architectural patterns for scalable distributed system some of which are as follows:

  1. Load Balancers: Load balancing is one of the easiest approach to provide some level of scalability. As well as hardware for load balancing, there are also software for it. In order for a load balancer to be implemented efficiently, units should have a shared nothing architecture. Once placed in front of application servers, load balancers distributes the load evenly across all the servers within the system. There are several load balancing algorithms, the most basic one is round robin. Some of other ones are based on some pattern, load balancing based on weighted graph and so on. Load balancing is a beautiful concept.
  2. Distributed Caching: Distributed Hash tables or caches are used in front of data storage for scaling up reads. Instead of querying data stores each time, querying an in memory caching system speed up applications. Some of the implementations are Memcached, Redis etc. Consistent hashing is used for in the clients. There is no notion of replication.
  3. Distributed Message Queues. Blocking Queue implementation (FIFO delivery) implemented as a network service. Distributed Message Queues are based on Producer/Consumer problem. There are several concepts with producer/consumer other known as publisher/subscriber pattern.  It is fairly easy to scale applications using this pattern.
  4. Gossip and Nature-inspired Architectures. Each node randomly pick and exchange information with follow nodes.
  5. Map Reduce/ Data flows. Scalable pattern to describe and execute Jobs.
  6. Tree of responsibility. Break the problem down recursively and assign to a tree, each parent node delegating work to children nodes.
  7. Stream processing. Process data streams, data that is keeps coming.
  8. Scalable Storages. Ranges from Databases, NoSQL storages, Service Registries, to File systems.

Floyd Cycle Finding Algorithms

Floyd cycle finding algorithm is used to find a cycle within a collection, graph, or container. A simple example would help understand better. Given a linked list, detect if it contains a cycle or not. If you use two pointers, one of which will traverse the linked list, two nodes at a time and another pointer that will traverse the linked list one node at a time, eventually they will meet at the cycle.

Stack with LinkedList Implementation

Naive implementation of Stack in C# uses array. In this post, I have implemented the stack with LinkedList. This implementation is not thread safe.

using System;
using System.Collections;
using System.Collections.Generic;

namespace CodeCodeCode
{
    public class StackLinkedList : IEnumerable, ICollection
    {
        private readonly LinkedList _container;

        public StackLinkedList()
        {
            _container = new LinkedList();
        }

        public StackLinkedList(IEnumerable collection)
        {
            foreach (T element in collection)
            {
                _container.AddLast(element);
            }
        }

        public StackLinkedList(Stack _stack)
        {
            while (_stack.Count > 0)
            {
                T element = _stack.Pop();

                _container.AddLast(element);
            }
        }

        #region ICollection Members

        public void Add(T item)
        {
            throw new NotImplementedException();
        }

        public void Clear()
        {
            _container.Clear();
        }

        public bool Contains(T item)
        {
            return _container.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        int ICollection.Count
        {
            get { return _container.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(T item)
        {
            return _container.Remove(item);
        }

        #endregion

        #region IEnumerable Members

        public IEnumerator GetEnumerator()
        {
            foreach (T element in _container)
            {
                yield return element;
                _container.Remove(element);
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        public T Pop()
        {
            LinkedListNode element = _container.First;

            _container.Remove(element);

            return element.Value;
        }

        public void Push(T element)
        {
            _container.AddFirst(element);
        }

        public T Peek()
        {
            return _container.First.Value;
        }

        public int Count()
        {
            return _container.Count;
        }
    }
}
    [TestClass]
    public class UnitTest1
    {

        private StackLinkedList _collection;

        public UnitTest1()
        {
            _collection = new StackLinkedList();
        }

        [TestMethod]
        public void PushMethod()
        {
             _collection.Push(1);
             _collection.Push(2);
             _collection.Push(3);
            Assert.AreEqual(3, _collection.Peek());
            Assert.AreEqual(3, _collection.Pop());
            Assert.AreEqual(2, _collection.Pop());
            Assert.AreEqual(1, _collection.Pop());
            Assert.AreEqual(0, _collection.Count());
        }

    }