Skip to content

Commit

Permalink
feat: Map + Set
Browse files Browse the repository at this point in the history
  • Loading branch information
Bnaya committed Nov 12, 2019
1 parent 5dad67a commit fb566c2
Show file tree
Hide file tree
Showing 13 changed files with 855 additions and 147 deletions.
166 changes: 166 additions & 0 deletions src/apiTests/Map.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/* eslint-env jest */

import * as util from "util";

import { createObjectBuffer } from "../";
import { memoryStats } from "../internal/api";
import { externalArgsApiToExternalArgsApi } from "../internal/utils";

describe("Map", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});

test("creation", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Map([[1, "a"]]);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`624`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`
Map {
1 => "a",
}
`);
});

test("add", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo.set("2", "b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`
Map {
1 => "a",
"2" => "b",
}
`);
});

test("has", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo.set("2", "b");
expect(objectBuffer.foo.has("2")).toEqual(true);
expect(objectBuffer.foo.has("none exiting")).toEqual(false);
});

test("delete", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo.set("2", "b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);

objectBuffer.foo.delete(1);

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`632`);

expect(objectBuffer.foo).toMatchInlineSnapshot(`
Map {
"2" => "b",
}
`);
});

test("clear", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo.set("2", "b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);

objectBuffer.foo.clear();

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`704`);

expect(objectBuffer.foo).toMatchInlineSnapshot(`
Map {
"2" => "b",
}
`);
});

test("iterate", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo.set("2", "b");

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);

expect(objectBuffer.foo).toMatchInlineSnapshot(`
Map {
1 => "a",
"2" => "b",
}
`);
expect([...objectBuffer.foo.keys()]).toMatchInlineSnapshot(`
Array [
1,
"2",
]
`);

expect([...objectBuffer.foo.values()]).toMatchInlineSnapshot(`
Array [
"a",
"b",
]
`);
});

// bug with deletion during iteration
test.skip("iterate + delete compare", () => {
const nativeMap = new Map([[1, "a"], [2, "b"]]);
for (const [key] of nativeMap) {
nativeMap.delete(key);
}

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {
foo: new Map([[1, "a"], [2, "b"]])
});
for (const [key] of objectBuffer.foo) {
objectBuffer.foo.delete(key);
}

expect(objectBuffer.foo).toEqual(nativeMap);
});

test("forEach", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo.set("2", "b");

const dump: any[] = [];
const thisArgs: any[] = [];

objectBuffer.foo.forEach((value: any, key: any, map: any) => {
thisArgs.push(map);
dump.push({ value, key });
});

expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true);

expect(dump).toMatchInlineSnapshot(`
Array [
Object {
"key": 1,
"value": "a",
},
Object {
"key": "2",
"value": "b",
},
]
`);
});
});
167 changes: 167 additions & 0 deletions src/apiTests/Set.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/* eslint-env jest */

import * as util from "util";

import { createObjectBuffer } from "../";
import { memoryStats } from "../internal/api";
import { externalArgsApiToExternalArgsApi } from "../internal/utils";

describe("Set tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});

test("creation", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Set(["a"]);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`648`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`
Set {
"a",
}
`);
});

test("add", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`576`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`
Set {
"a",
"b",
}
`);
});

test("has", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");
expect(objectBuffer.foo.has("b")).toEqual(true);
expect(objectBuffer.foo.has("none exiting")).toEqual(false);
});

test("delete", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`576`);

objectBuffer.foo.delete(1);

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`576`);

expect(objectBuffer.foo).toMatchInlineSnapshot(`
Set {
"a",
"b",
}
`);
});

test("clear", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`576`);

objectBuffer.foo.clear();

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`632`);

expect(objectBuffer.foo).toMatchInlineSnapshot(`
Set {
"b",
}
`);
});

test("iterate", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`576`);

expect(objectBuffer.foo).toMatchInlineSnapshot(`
Set {
"a",
"b",
}
`);
expect([...objectBuffer.foo.keys()]).toMatchInlineSnapshot(`
Array [
"a",
"b",
]
`);

expect([...objectBuffer.foo.values()]).toMatchInlineSnapshot(`
Array [
"a",
"b",
]
`);
});

// bug with deletion during iteration
test.skip("iterate + delete compare", () => {
const nativeMap = new Set(["a", "b"]);
for (const [key] of nativeMap) {
nativeMap.delete(key);
}

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {
foo: new Set(["a", "b"])
});
for (const [key] of objectBuffer.foo) {
objectBuffer.foo.delete(key);
}

expect(objectBuffer.foo).toEqual(nativeMap);
});

test("forEach", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);

objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");

const dump: any[] = [];
const thisArgs: any[] = [];

objectBuffer.foo.forEach((value: any, key: any, map: any) => {
thisArgs.push(map);
dump.push({ value, key });
});

expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true);

expect(dump).toMatchInlineSnapshot(`
Array [
Object {
"key": "a",
"value": "a",
},
Object {
"key": "b",
"value": "b",
},
]
`);
});
});
9 changes: 6 additions & 3 deletions src/internal/BaseProxyTrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import {
InternalAPI,
DateEntry,
ArrayEntry,
ObjectEntry
ObjectEntry,
MapEntry,
SetEntry
} from "./interfaces";
import { IMemPool } from "@thi.ng/malloc";
import { incrementRefCount, decrementRefCount, readEntry } from "./store";
import { WrapperDestroyed } from "./exceptions";

export class BaseProxyTrap<T extends ObjectEntry | DateEntry | ArrayEntry>
implements InternalAPI {
export class BaseProxyTrap<
T extends ObjectEntry | DateEntry | ArrayEntry | MapEntry | SetEntry
> implements InternalAPI {
constructor(
protected externalArgs: ExternalArgs,
protected carrier: DataViewAndAllocatorCarrier,
Expand Down
1 change: 1 addition & 0 deletions src/internal/entry-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export enum ENTRY_TYPE {
STRING,
BOOLEAN,
OBJECT,
// deprecated
OBJECT_PROP,
ARRAY,
ARRAY_ITEM,
Expand Down

0 comments on commit fb566c2

Please sign in to comment.