{ "info": { "author": "Geetesh Gupta", "author_email": "ggguitarg31@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# python3-crdt\nA python library for CRDTs (Conflict-free Replicated Data types)\n\n## Installation\nYou can get the library directly from PyPI:\n\n```python\npip install python3-crdt\n```\n\n## Usage\nIf you have installed the python3-crdt package you can start using the crdts right away:\n```python\nfrom py3crdt.gset import GSet\ngset1 = GSet(id=1)\ngset2 = GSet(id=2)\ngset1.add('a')\ngset1.add('b')\ngset1.display()\n# ['a', 'b'] ----- Output\ngset2.add('b')\ngset2.add('c')\ngset2.display()\n# ['b', 'c'] ----- Output\ngset1.merge(gset2) \ngset1.display()\n# ['a', 'b', 'c'] ----- Output\ngset2.merge(gset1)\ngset2.display()\n# ['a', 'b', 'c'] ----- Output\n```\n\n#### CRDTs deployed:-\n- gcounter.GCounter\n- pncounter.PNCounter\n- gset.GSet\n- twopset.TwoPSet\n- lww.LWWElementSet\n- orest.ORSet\n- sequence.Sequence\n\n## API\n- add()\n- remove()\n- merge()\n- display()\n- query()\n\n## Testing\nUse following command to test packages\n```python\npython -m unittest tests.test_\n``` \n## Intro to CRDTs\n#### What are CRDTS?\nCRDTs or Conflict-Free Replicated Data Types are data structures which eases the replication of data across multiple devices in a network. Any change/update is applied locally and then transmitted to other replicas. Each replica merges it\u2019s local replica with the incoming change/update. Inconsistencies might arise during merging but CRDTs mathematically guarantees that the replicas will converge eventually if all the changes/updates are executed by each replica. \n\n#### Types of CRDTs\n\n##### Operation-based CRDTs\nIn these CRDTs, change/update operations are transmitted to other replicas. Each replica receives the operations and apply the operations to its local state. These are also known as CmRDT (Commutative Replicated Data Type) because the operations are commutative hence, order of sending operations does not matter. The resulting state will eventually be the same. But the operations are not idempotent hence, it must be ensured that no operation is duplicated during transmission.\n\n##### State-based CRDTs\nIn these CRDTs, full state is transmitted to other replicas. Replicas receive the state and merge it with the local state. Merge function is commutative as CmRDTs but is also idempotent and associative. These are also known as CvRDT (Convergent Replicated Data Type) because in every transmission merging of states occur, which eventually results in all replicas converging to the same state.\n\n##### Delta-state CRDTs\nIn these CRDTs, instead of full state, only recently applied changes are transmitted to other replicas. It is just an optimised State-based CRDT.\n\n#### Comparison between CmRDTs & CvRDTs\nCmRDTs increases transmission mechanism workload but consumes less bandwidth than CvRDTs when number of transactions is small compared to size of the internal state. However, since the CvRDT merge function is associative merging the state produces all previous updates to that replica and since it is idempotent, the states can be transmitted multiple number of times but resulting into the same state.\n\n## CRDTs deployed in this library\n\n#### G-Counter (Grow-only Counter)\nIt implements an array of nodes where the value of array works as a counter. The value of array is sum of the values of the nodes in the array. Each node is assigned an ID equivalent to the index of the node in the array. The array is an equivalent for a cluster of nodes. Updating involves each node incrementing its own index value in the array. Merging occurs by taking the maximum of every node value in the cluster. Comparison function is included to verify the increments. Internal state is monotonically increased by application of each update function according to the compare function.\n\n#### PN-Counter (Positive-Negative Counter)\nThis counter supports both increment and decrement operations. It combines two G-Counters namely \u201cP\u201d (for incrementing) and \u201cN\u201d (for decrementing) counter. The value of the counter is the value of the P counter minus the value of the N counter. Merging involves merging the P and N counter independently.\n\n#### G-Set (Grow-only Set)\nThis involves creating a set of elements where elements can only be added and once and element is added, it cannot be removed. Merging returns union of the two G-Sets.\n\n#### 2P-Set (Two-Phase Set)\nIt involves creating a set in which elements can be added as well as removed. Similar to PN-Counter, it combines two G-Sets namely \u201cadd\u201d and \u201cremove\u201d set. For adding/removing an element, it is inserted in the \u201cadd\u201d/\u201cremove\u201d set. An element is a member of the set if it is in the \u201cadd\u201d set but not in the \u201cremove\u201d set. Query function returns whether the element is a member of the set or not. Hence, if an element is removed, query will never return True for that element, so it cannot be re-added. Merging involves union of the \u201cadd\u201d/\u201cremove\u201d sets.\n\n#### LWW-Element-Set (Last-Write-Wins-Element-Set)\nSimilar to 2P-Set except each element is added/removed with a timestamp. An element is a member of the set if it is in the \u201cadd\u201d set but not in the \u201cremove\u201d set, or if it is in both the \u201cadd\u201d and \u201cremove\u201d set then timestamp in \u201cremove\u201d set should be less than that of the latest timestamp in \u201cadd\u201d set. \u201cBias\u201d comes into play, if timestamps are equal which can be towards \u201cadd\u201d or \u201cremove\u201d. In this set, an element can be reinserted after being removed and thus, it has an advantage over 2P-Set.\n\n#### OR-Set (Observed-Removed Set)\nSimilar to LWW-Element-Set, except that it unique tags are used instead of timestamps. For each element, a list of add/remove tags are maintained. An element is added by adding a newly generated unique tag to the add-tag list for the element. Removing an element involves copying all the tags in it\u2019s add-tag list to it's remove-tag list. An element is a member of the set iff there exists a tag in add-tag list which is not in remove-tag list.\n\n#### Sequence CRDTs\nIt involves an ordered set, list or a sequence of elements. This CRDT can be build on top of other Set based CRDTs by sorting them on some basis. \nWe have used this CRDT to build a Collaborative Code/Text Editor.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/geetesh-gupta/python3-crdt", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "python3-crdt", "package_url": "https://pypi.org/project/python3-crdt/", "platform": "", "project_url": "https://pypi.org/project/python3-crdt/", "project_urls": { "Homepage": "https://github.com/geetesh-gupta/python3-crdt" }, "release_url": "https://pypi.org/project/python3-crdt/1.0.3/", "requires_dist": null, "requires_python": "", "summary": "A python library for CRDTs (Conflict-free Replicated Data types)", "version": "1.0.3" }, "last_serial": 5272726, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "e22c874225a259a14fbc4bdfdfa186cf", "sha256": "0c8ae30ec5fbe770781822a52f7be28b3b38fd8e5fe553583c2c0516002ac59d" }, "downloads": -1, "filename": "python3_crdt-1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "e22c874225a259a14fbc4bdfdfa186cf", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 13847, "upload_time": "2019-04-22T11:37:54", "url": "https://files.pythonhosted.org/packages/8f/3b/1ee000d2be30c91be1927aeefafb66cf3582c264996b3be784281582d081/python3_crdt-1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "10782ae9b4750e543cc31fa09b9ddbb7", "sha256": "db2c4d2f4c69579f3132d69467c41923dc99c89f3f9af22e32bb5233a9237a80" }, "downloads": -1, "filename": "python3-crdt-1.0.tar.gz", "has_sig": false, "md5_digest": "10782ae9b4750e543cc31fa09b9ddbb7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8208, "upload_time": "2019-04-22T11:37:56", "url": "https://files.pythonhosted.org/packages/a5/c8/a1a208a43669fd07dd4bd2a4b47d03cd61a00c2f8bdb2352220398ca69dc/python3-crdt-1.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "68d6d04f62f49cc9305858088df9a724", "sha256": "91b9b95252436c783e47a7aeaf35ec72e2d427530846d0cceb1a5c0f3ace2ae1" }, "downloads": -1, "filename": "python3-crdt-1.0.1.tar.gz", "has_sig": false, "md5_digest": "68d6d04f62f49cc9305858088df9a724", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9280, "upload_time": "2019-04-25T08:36:17", "url": "https://files.pythonhosted.org/packages/68/07/3bd951b4bcb5f786f95286e0f109783bdbaad76c250da54d74be5ee94159/python3-crdt-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "92541fa986fe20b91aba8b1861cf809a", "sha256": "123d4f1b3926ceb20b358a68194e601bc5614b5115970de3e47cd6dbb73f8cae" }, "downloads": -1, "filename": "python3-crdt-1.0.2.tar.gz", "has_sig": false, "md5_digest": "92541fa986fe20b91aba8b1861cf809a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9303, "upload_time": "2019-04-25T09:15:43", "url": "https://files.pythonhosted.org/packages/d4/d9/ce91b29ee2671ecc476006a0229f925a0e0ed73784b03cc62d5b3475d17d/python3-crdt-1.0.2.tar.gz" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "7d825063361e7905d4f050d5399289b5", "sha256": "940ed69583ce3b8a2cd0f69c780c796856812f5056a298c116958587e75831e2" }, "downloads": -1, "filename": "python3_crdt-1.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "7d825063361e7905d4f050d5399289b5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 43229, "upload_time": "2019-05-15T14:23:15", "url": "https://files.pythonhosted.org/packages/4f/a6/0efe0280f988d7e62300c81da97cbc6b8223c0825efcf3e114794bb847a2/python3_crdt-1.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "009d08643b3f79fd34a4eee0a8c1dc1e", "sha256": "41ba08e163de5d99783e97896aadb64bb4e6e1c6c3599474195154380cf02d2a" }, "downloads": -1, "filename": "python3-crdt-1.0.3.tar.gz", "has_sig": false, "md5_digest": "009d08643b3f79fd34a4eee0a8c1dc1e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13000, "upload_time": "2019-05-15T14:23:20", "url": "https://files.pythonhosted.org/packages/1e/d3/7cc57bc3460e9c8dc40de88c656d16bd220d04ca51ed51bf489df943d9e5/python3-crdt-1.0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7d825063361e7905d4f050d5399289b5", "sha256": "940ed69583ce3b8a2cd0f69c780c796856812f5056a298c116958587e75831e2" }, "downloads": -1, "filename": "python3_crdt-1.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "7d825063361e7905d4f050d5399289b5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 43229, "upload_time": "2019-05-15T14:23:15", "url": "https://files.pythonhosted.org/packages/4f/a6/0efe0280f988d7e62300c81da97cbc6b8223c0825efcf3e114794bb847a2/python3_crdt-1.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "009d08643b3f79fd34a4eee0a8c1dc1e", "sha256": "41ba08e163de5d99783e97896aadb64bb4e6e1c6c3599474195154380cf02d2a" }, "downloads": -1, "filename": "python3-crdt-1.0.3.tar.gz", "has_sig": false, "md5_digest": "009d08643b3f79fd34a4eee0a8c1dc1e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13000, "upload_time": "2019-05-15T14:23:20", "url": "https://files.pythonhosted.org/packages/1e/d3/7cc57bc3460e9c8dc40de88c656d16bd220d04ca51ed51bf489df943d9e5/python3-crdt-1.0.3.tar.gz" } ] }