Skip to content

Commit

Permalink
Merge 0132d92 into c11db57
Browse files Browse the repository at this point in the history
  • Loading branch information
divyanshyadav committed Dec 3, 2020
2 parents c11db57 + 0132d92 commit f9673dc
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 1 deletion.
21 changes: 20 additions & 1 deletion README.md
Expand Up @@ -20,6 +20,7 @@ Light weight javascript data structures library
- Heap
- Graph
- Disjoint-set
- LRU Cache (New!)
- HashSet

## Installation and Usage
Expand Down Expand Up @@ -124,6 +125,25 @@ ds.isConnected('a', 'd') // true

```

### LRUCache

```js
const { LRUCache } = require("data-structures-again");

const lru = new LRUCache(2)

lru.put(1, 1)
lru.put(2, 2)
lru.get(1) // 1
lru.put(3, 3)
lru.get(2) // -1
lru.put(4, 4)
lru.get(1) // -1
lru.get(3) // 3
lru.get(4) // 4

```

### Hash-set

```js
Expand All @@ -140,7 +160,6 @@ set.has(3)) // false
```



## License

MIT.
3 changes: 3 additions & 0 deletions index.js
Expand Up @@ -4,14 +4,17 @@ const Queue = require('./src/queue')
const Heap = require('./src/heap')
const Graph = require('./src/graph')
const DisjointSet = require('./src/disjoint-set')
const LRUCache = require('./src/lru-cache')
const HashSet = require('./src/hash-set')


module.exports = {
BST,
Stack,
Queue,
Heap,
Graph,
DisjointSet,
LRUCache,
HashSet
}
18 changes: 18 additions & 0 deletions index.test.js
Expand Up @@ -72,6 +72,23 @@ test('disjoint-set example', () => {
expect(ds.isConnected('a', 'd')).toBeTruthy()
})


test('LRU Cache example', () => {
const { LRUCache } = require('./index')

const lru = new LRUCache(2)

lru.put(1, 1)
lru.put(2, 2)
lru.get(1) // 1
lru.put(3, 3)
lru.get(2) // -1
lru.put(4, 4)
lru.get(1) // -1
lru.get(3) // 3
lru.get(4) // 4
})

test('hash-set example', () => {
const { HashSet } = require('./index')

Expand All @@ -82,4 +99,5 @@ test('hash-set example', () => {
expect(set.has(1)).toBeTruthy() // true
expect(set.has(2)).toBeTruthy()
expect(set.has(3)).toBeFalsy()

})
102 changes: 102 additions & 0 deletions src/lru-cache/LRUCacheHDLL.js
@@ -0,0 +1,102 @@
/*
LRU Cache build using hashmap and doubly-linked-list
capacity = n
Operations
put(key, value) O(1)
get(key) O(1)
*/

class Node {
constructor (key, value) {
this.key = key
this.value = value
this.prev = null
this.next = null
}
}

class LRUCacheHDLL {
constructor (capacity) {
this.capacity = capacity
this.head = null
this.tail = null
this.size = 0
this.map = new Map()
}

put (key, value) {
let node
if (this.map.has(key)) {
node = this.map.get(key)
node.value = value
this._moveToTail(node)
} else {
node = new Node(key, value)
this.map.set(key, node)

if (this.size + 1 > this.capacity) {
this._deleteNodeAtTail()
} else {
this.size++
}

this._insertNodeAtTail(node)
}
}

get (key) {
if (this.map.has(key)) {
const node = this.map.get(key)
this._moveToTail(node)
return node.value
}

return -1
}

_insertNodeAtTail (node) {
if (this.head === null) {
this.head = node
this.tail = node
} else {
this.tail.next = node
node.next = null
node.prev = this.tail
this.tail = node
}
}

_moveToTail (node) {
if (this.tail !== node) {
if (node === this.head) {
this.head = this.head.next
this.head.prev = null
} else {
const prev = node.prev
const next = node.next

prev.next = next
next.prev = prev
}

this.tail.next = node
node.next = null
node.prev = this.tail
this.tail = node
}
}

_deleteNodeAtTail () {
const temp = this.head
this.head = this.head.next
if (this.head) { this.head.prev = null }

temp.next = null
temp.prev = null
this.map.delete(temp.key)
}
}

module.exports = LRUCacheHDLL
42 changes: 42 additions & 0 deletions src/lru-cache/LRUCacheHDLL.test.js
@@ -0,0 +1,42 @@
const LRUCache = require('./LRUCacheHDLL')

test('get existing key', () => {
const lru = new LRUCache(1)
lru.put('key', 'value')
expect(lru.get('key')).toBe('value')
})

test('get non-existing key', () => {
const lru = new LRUCache(1)
expect(lru.get('key')).toBe(-1)
})

test('put value of existing key', () => {
const lru = new LRUCache(1)
lru.put('key', 'value')
lru.put('key', 'value2')

expect(lru.get('key')).toBe('value2')
})

test('put value of non existing key', () => {
const lru = new LRUCache(1)
lru.put('key', 'value')
lru.put('key2', 'value2')

expect(lru.get('key')).toBe(-1)
expect(lru.get('key2')).toBe('value2')
})

test('all cases', () => {
const lru = new LRUCache(2)
lru.put(1, 1)
lru.put(2, 2)
expect(lru.get(1)).toBe(1)
lru.put(3, 3)
expect(lru.get(2)).toBe(-1)
lru.put(4, 4)
expect(lru.get(1)).toBe(-1)
expect(lru.get(3)).toBe(3)
expect(lru.get(4)).toBe(4)
})

0 comments on commit f9673dc

Please sign in to comment.