Skip to content

Commit 95e40f5

Browse files
committed
✨ feat: implement '@algorithm.ts/circular-queue'
1 parent 5d6df88 commit 95e40f5

File tree

8 files changed

+494
-0
lines changed

8 files changed

+494
-0
lines changed

Diff for: packages/circular-queue/README.md

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<header>
2+
<h1 align="center">
3+
<a href="https://github.com/guanghechen/algorithm.ts/tree/main/packages/circular-queue#readme">@algorithm.ts/circular-queue</a>
4+
</h1>
5+
<div align="center">
6+
<a href="https://www.npmjs.com/package/@algorithm.ts/circular-queue">
7+
<img
8+
alt="Npm Version"
9+
src="https://img.shields.io/npm/v/@algorithm.ts/circular-queue.svg"
10+
/>
11+
</a>
12+
<a href="https://www.npmjs.com/package/@algorithm.ts/circular-queue">
13+
<img
14+
alt="Npm Download"
15+
src="https://img.shields.io/npm/dm/@algorithm.ts/circular-queue.svg"
16+
/>
17+
</a>
18+
<a href="https://www.npmjs.com/package/@algorithm.ts/circular-queue">
19+
<img
20+
alt="Npm License"
21+
src="https://img.shields.io/npm/l/@algorithm.ts/circular-queue.svg"
22+
/>
23+
</a>
24+
<a href="#install">
25+
<img
26+
alt="Module Formats: cjs, esm"
27+
src="https://img.shields.io/badge/module_formats-cjs%2C%20esm-green.svg"
28+
/>
29+
</a>
30+
<a href="https://github.com/nodejs/node">
31+
<img
32+
alt="Node.js Version"
33+
src="https://img.shields.io/node/v/@algorithm.ts/circular-queue"
34+
/>
35+
</a>
36+
<a href="https://github.com/facebook/jest">
37+
<img
38+
alt="Tested with Jest"
39+
src="https://img.shields.io/badge/tested_with-jest-9c465e.svg"
40+
/>
41+
</a>
42+
<a href="https://github.com/prettier/prettier">
43+
<img
44+
alt="Code Style: prettier"
45+
src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square"
46+
/>
47+
</a>
48+
</div>
49+
</header>
50+
<br/>
51+
52+
53+
A typescript implementation of the **Circular Queue** data structure.
54+
55+
Circular queue is a queue structure, the main purpose of its design is to
56+
reuse space as much as possible on the basis of ordinary queues. Circular
57+
queues usually need to specify the maximum volume C of the collector. If the
58+
number of elements in the queue exceeds C, only the most recent C elements
59+
are kept in the queue. Other operations are the same as ordinary queues.
60+
61+
62+
## Install
63+
64+
* npm
65+
66+
```bash
67+
npm install --save @algorithm.ts/circular-queue
68+
```
69+
70+
* yarn
71+
72+
```bash
73+
yarn add @algorithm.ts/circular-queue
74+
```
75+
76+
## Usage
77+
78+
* Basic:
79+
80+
```typescript
81+
import { createCircularQueue } from '@algorithm.ts/circular-queue'
82+
83+
const queue = createCircularQueue<{ name: string }>()
84+
85+
// Initialize the circular-queue with the maximum number of elements it can
86+
// be managed.
87+
queue.init(100)
88+
89+
// Append a element to the end of the queue.
90+
queue.enqueue({ name: 'alice' }) // => 0
91+
queue.enqueue({ name: 'bob' }) // => 1
92+
queue.size() // => 2
93+
94+
// Get the front element of the queue.
95+
queue.front() // => { name: 'alice' }
96+
97+
// Get the last element of the queue.
98+
queue.end() // => { name: 'bob' }
99+
100+
// Take off the first element of the queue.
101+
queue.dequeue() // => { name: 'alice' }
102+
queue.size() // => 1
103+
104+
// Test if the queue is empty.
105+
queue.isEmpty() // => false
106+
107+
queue.get(0) // undefined
108+
queue.get(0, true) // undefined
109+
queue.get(0, false) // { name: 'alice' }
110+
111+
queue.get(1) // => { name: 'bob' }
112+
queue.get(1, true) // => { name: 'bob' }
113+
queue.get(1, false) // => { name: 'bob' }
114+
```
115+
116+
117+
## Related
118+
119+
120+
[homepage]: https://github.com/guanghechen/algorithm.ts/tree/main/packages/circular-queue#readme
+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import { createCircularQueue } from '../src'
2+
3+
describe('createCircularQueue', function () {
4+
const _size = 100
5+
6+
test('basic', function () {
7+
const queue = createCircularQueue()
8+
queue.init(_size)
9+
for (let i = 0; i < _size; ++i) {
10+
const x = queue.enqueue(i)
11+
expect(queue.get(x)).toBe(i)
12+
expect(queue.size()).toBe(i + 1)
13+
expect(queue.end()).toBe(x)
14+
}
15+
16+
let cnt = 0
17+
for (let i = 0; !queue.isEmpty(); ++i, ++cnt) {
18+
expect(queue.front()).toBe(i)
19+
20+
const x = queue.dequeue()
21+
expect(x).toBe(i)
22+
}
23+
24+
expect(cnt).toBe(_size)
25+
expect(queue.front()).toBe(undefined)
26+
expect(queue.end()).toBe(undefined)
27+
expect(queue.isEmpty()).toBe(true)
28+
expect(queue.size()).toBe(0)
29+
30+
expect(queue.dequeue()).toBe(undefined)
31+
expect(queue.size()).toBe(0)
32+
})
33+
34+
test('excess', function () {
35+
const queue = createCircularQueue()
36+
queue.init(_size)
37+
for (let i = 0; i < _size; ++i) {
38+
expect(queue.size()).toBe(i)
39+
expect(queue.enqueue(i)).toBe(i)
40+
}
41+
42+
expect(queue.size()).toBe(_size)
43+
for (let i = 0; i < _size; ++i) {
44+
expect(queue.enqueue(100 + i)).toBe(i)
45+
expect(queue.size()).toBe(_size)
46+
}
47+
48+
expect(queue.size()).toBe(_size)
49+
for (let i = 0; i < _size; ++i) {
50+
expect(queue.enqueue(200 + i)).toBe(i)
51+
expect(queue.size()).toBe(_size)
52+
}
53+
54+
for (let i = 0; i < _size; ++i) expect(queue.get(i)).toBe(200 + i)
55+
})
56+
57+
test('invalid', function () {
58+
const queue = createCircularQueue()
59+
queue.init(_size)
60+
61+
expect(queue.isValidIndex(-1)).toBe(false)
62+
expect(queue.isValidIndex(0)).toBe(false)
63+
expect(queue.isValidIndex(1)).toBe(false)
64+
expect(queue.isValidIndex(-1)).toBe(false)
65+
expect(queue.isValidIndex(_size)).toBe(false)
66+
expect(queue.isValidIndex(_size + 1)).toBe(false)
67+
68+
queue.enqueue(1)
69+
queue.enqueue(2)
70+
expect(queue.isValidIndex(-1)).toBe(false)
71+
expect(queue.isValidIndex(0)).toBe(true)
72+
expect(queue.isValidIndex(1)).toBe(true)
73+
expect(queue.isValidIndex(2)).toBe(false)
74+
expect(queue.isValidIndex(3)).toBe(false)
75+
expect(queue.isValidIndex(-1)).toBe(false)
76+
expect(queue.isValidIndex(_size)).toBe(false)
77+
expect(queue.isValidIndex(_size + 1)).toBe(false)
78+
79+
queue.dequeue()
80+
expect(queue.isValidIndex(-1)).toBe(false)
81+
expect(queue.isValidIndex(0)).toBe(false)
82+
expect(queue.isValidIndex(1)).toBe(true)
83+
expect(queue.isValidIndex(2)).toBe(false)
84+
expect(queue.isValidIndex(3)).toBe(false)
85+
expect(queue.isValidIndex(-1)).toBe(false)
86+
expect(queue.isValidIndex(_size)).toBe(false)
87+
expect(queue.isValidIndex(_size + 1)).toBe(false)
88+
89+
queue.enqueue(9)
90+
expect(queue.isValidIndex(-1)).toBe(false)
91+
expect(queue.isValidIndex(0)).toBe(false)
92+
expect(queue.isValidIndex(1)).toBe(true)
93+
expect(queue.isValidIndex(2)).toBe(true)
94+
expect(queue.isValidIndex(3)).toBe(false)
95+
expect(queue.isValidIndex(-1)).toBe(false)
96+
expect(queue.isValidIndex(_size)).toBe(false)
97+
expect(queue.isValidIndex(_size + 1)).toBe(false)
98+
99+
expect(queue.get(1)).toBe(2)
100+
expect(queue.get(2)).toBe(9)
101+
102+
expect(queue.set(0, 10)).toBe(false)
103+
expect(queue.set(1, 10)).toBe(true)
104+
105+
expect(queue.get(0)).toBe(undefined)
106+
expect(queue.get(0, true)).toBe(undefined)
107+
expect(queue.get(0, false)).toBe(1)
108+
109+
expect(queue.get(1)).toBe(10)
110+
expect(queue.get(2)).toBe(9)
111+
expect(queue.get(3)).toBe(undefined)
112+
})
113+
114+
test('init', function () {
115+
const queue = createCircularQueue()
116+
queue.init(2)
117+
expect(queue.size()).toBe(0)
118+
119+
queue.enqueue(1)
120+
queue.enqueue(2)
121+
expect(queue.get(0)).toBe(1)
122+
expect(queue.get(1)).toBe(2)
123+
124+
queue.enqueue(4)
125+
expect(queue.get(0)).toBe(4)
126+
expect(queue.get(1)).toBe(2)
127+
expect(queue.size()).toBe(2)
128+
expect(queue.size()).toBe(2)
129+
130+
queue.init(3)
131+
expect(queue.size()).toBe(0)
132+
133+
queue.enqueue(1)
134+
queue.enqueue(2)
135+
expect(queue.get(0)).toBe(1)
136+
expect(queue.get(1)).toBe(2)
137+
expect(queue.get(2)).toBe(undefined)
138+
139+
queue.enqueue(4)
140+
expect(queue.get(0)).toBe(1)
141+
expect(queue.get(1)).toBe(2)
142+
expect(queue.get(2)).toBe(4)
143+
expect(queue.size()).toBe(3)
144+
145+
queue.init(2)
146+
expect(queue.size()).toBe(0)
147+
148+
queue.enqueue(1)
149+
queue.enqueue(2)
150+
expect(queue.get(0)).toBe(1)
151+
expect(queue.get(1)).toBe(2)
152+
153+
queue.enqueue(4)
154+
expect(queue.get(0)).toBe(4)
155+
expect(queue.get(1)).toBe(2)
156+
expect(queue.size()).toBe(2)
157+
expect(queue.size()).toBe(2)
158+
})
159+
})

Diff for: packages/circular-queue/package.json

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "@algorithm.ts/circular-queue",
3+
"version": "1.0.6",
4+
"description": "Circular queue in Typescript",
5+
"author": {
6+
"name": "guanghechen",
7+
"url": "https://github.com/guanghechen/"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/guanghechen/algorithm.ts.git",
12+
"directory": "packages/circular-queue"
13+
},
14+
"homepage": "https://github.com/guanghechen/algorithm.ts/tree/main/packages/circular-queue#readme",
15+
"keywords": [
16+
"queue",
17+
"circular queue"
18+
],
19+
"main": "lib/cjs/index.js",
20+
"module": "lib/esm/index.js",
21+
"types": "lib/types/index.d.ts",
22+
"source": "src/index.ts",
23+
"license": "MIT",
24+
"engines": {
25+
"node": ">= 14.15.0"
26+
},
27+
"files": [
28+
"lib/",
29+
"!lib/**/*.js.map",
30+
"!lib/**/*.d.ts.map",
31+
"package.json",
32+
"CHANGELOG.md",
33+
"LICENSE",
34+
"README.md"
35+
],
36+
"scripts": {
37+
"build": "cross-env NODE_ENV=production rollup -c ../../rollup.config.js",
38+
"prebuild": "rimraf lib/ && tsc -p tsconfig.src.json --emitDeclarationOnly",
39+
"prepublishOnly": "cross-env ROLLUP_SHOULD_SOURCEMAP=false yarn build",
40+
"test": "cross-env TS_NODE_FILES=true jest --config ../../jest.config.js --rootDir ."
41+
}
42+
}

0 commit comments

Comments
 (0)