Skip to content

Commit

Permalink
refactor(daemon): Fix naming issues in multimap interface
Browse files Browse the repository at this point in the history
Addresses some naming issues in the multimap's interface and adds
missing test cases.
  • Loading branch information
rekmarks committed Mar 30, 2024
1 parent c8c99bf commit 13bbec1
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 96 deletions.
25 changes: 9 additions & 16 deletions packages/daemon/src/multimap.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const internalMakeMultimap = mapConstructor => {

get: key => map.get(key)?.keys().next().value,

getAll: key => Array.from(map.get(key) ?? []),
getAllFor: key => Array.from(map.get(key) ?? []),
};
};

Expand All @@ -58,12 +58,9 @@ export const makeWeakMultimap = () => {
*/
export const makeBidirectionalMultimap = () => {
/**
* @type {import('./types.js').Multimap<any, any>}
* @type {import('./types.js').Multimap<unknown, unknown>}
*/
const keyForValues = internalMakeMultimap(Map);
/**
* @type {Map<any, any>}
*/
const valueForKey = new Map();

return {
Expand All @@ -79,8 +76,8 @@ export const makeBidirectionalMultimap = () => {
);
}

valueForKey.set(value, key);
keyForValues.add(key, value);
valueForKey.set(value, key);
},

delete: (key, value) => {
Expand All @@ -89,24 +86,20 @@ export const makeBidirectionalMultimap = () => {
},

deleteAll: key => {
for (const value of keyForValues.getAll(key)) {
for (const value of keyForValues.getAllFor(key)) {
valueForKey.delete(value);
}
return keyForValues.deleteAll(key);
},

hasValue: value => {
return valueForKey.has(value);
},
hasValue: value => valueForKey.has(value),

get: value => valueForKey.get(value),
get: key => keyForValues.get(key),

getValue: key => keyForValues.get(key),
getKey: value => valueForKey.get(value),

getAllValues: () => {
return [...valueForKey.keys()];
},
getAll: () => [...valueForKey.keys()],

getAllValuesFor: key => keyForValues.getAll(key),
getAllFor: key => keyForValues.getAllFor(key),
};
};
18 changes: 9 additions & 9 deletions packages/daemon/src/pet-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const makePetStoreMaker = (filePowers, locator) => {
/** @type {import('./types.js').PetStore['identifyLocal']} */
const identifyLocal = petName => {
assertValidName(petName);
return idsToPetNames.get(petName);
return idsToPetNames.getKey(petName);
};

/** @type {import('./types.js').PetStore['write']} */
Expand All @@ -60,7 +60,7 @@ export const makePetStoreMaker = (filePowers, locator) => {
assertValidId(formulaIdentifier);

if (idsToPetNames.hasValue(petName)) {
const oldFormulaIdentifier = idsToPetNames.get(petName);
const oldFormulaIdentifier = idsToPetNames.getKey(petName);
if (oldFormulaIdentifier === formulaIdentifier) {
return;
}
Expand Down Expand Up @@ -89,20 +89,20 @@ export const makePetStoreMaker = (filePowers, locator) => {
* @returns {import('./types.js').IdRecord}
*/
const formulaIdentifierRecordForName = petName => {
const formulaIdentifier = idsToPetNames.get(petName);
const formulaIdentifier = idsToPetNames.getKey(petName);
if (formulaIdentifier === undefined) {
throw new Error(`Formula does not exist for pet name ${q(petName)}`);
}
return parseId(formulaIdentifier);
};

/** @type {import('./types.js').PetStore['list']} */
const list = () => harden(idsToPetNames.getAllValues().sort());
const list = () => harden(idsToPetNames.getAll().sort());

/** @type {import('./types.js').PetStore['follow']} */
const follow = async function* currentAndSubsequentNames() {
const changes = nameChangesTopic.subscribe();
for (const name of idsToPetNames.getAllValues().sort()) {
for (const name of idsToPetNames.getAll().sort()) {
const formulaIdentifierRecord = formulaIdentifierRecordForName(name);
yield /** @type {{ add: string, value: import('./types.js').IdRecord }} */ ({
add: name,
Expand All @@ -115,7 +115,7 @@ export const makePetStoreMaker = (filePowers, locator) => {
/** @type {import('./types.js').PetStore['remove']} */
const remove = async petName => {
assertValidName(petName);
const formulaIdentifier = idsToPetNames.get(petName);
const formulaIdentifier = idsToPetNames.getKey(petName);
if (formulaIdentifier === undefined) {
throw new Error(
`Formula does not exist for pet name ${JSON.stringify(petName)}`,
Expand All @@ -138,8 +138,8 @@ export const makePetStoreMaker = (filePowers, locator) => {
if (fromName === toName) {
return;
}
const formulaIdentifier = idsToPetNames.get(fromName);
const overwrittenId = idsToPetNames.get(toName);
const formulaIdentifier = idsToPetNames.getKey(fromName);
const overwrittenId = idsToPetNames.getKey(toName);
if (formulaIdentifier === undefined) {
throw new Error(
`Formula does not exist for pet name ${JSON.stringify(fromName)}`,
Expand Down Expand Up @@ -174,7 +174,7 @@ export const makePetStoreMaker = (filePowers, locator) => {
/** @type {import('./types.js').PetStore['reverseIdentify']} */
const reverseIdentify = formulaIdentifier => {
assertValidId(formulaIdentifier);
const formulaPetNames = idsToPetNames.getAllValuesFor(formulaIdentifier);
const formulaPetNames = idsToPetNames.getAllFor(formulaIdentifier);
if (formulaPetNames === undefined) {
return harden([]);
}
Expand Down
24 changes: 12 additions & 12 deletions packages/daemon/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ export type Multimap<K, V> = {
* @param key - The key whose values to retrieve.
* @returns An array of all values associated with the key.
*/
getAll(key: K): V[];
getAllFor(key: K): V[];
};

/**
Expand All @@ -924,37 +924,37 @@ export type BidirectionalMultimap<K, V> = {
delete(key: K, value: V): boolean;

/**
* @param key - The key whose values to delete
* @param key - The key whose values to delete.
* @returns `true` if the key was found and its values were deleted, `false` otherwise.
*/
deleteAll(key: K): boolean;

/**
* @param value - The value whose existence to check for.
* @returns `true` if the value was found and `false` otherwise.
* @param value - The value whose presence to check for.
* @returns `true` if the value is present and `false` otherwise.
*/
hasValue(value: V): boolean;

/**
* @param value - The value whose key to retrieve
* @returns The key associated with the value.
* @param key - The key whose first value to retrieve.
* @returns The first value associated with the key.
*/
get(value: V): K | undefined;
get(key: K): V | undefined;

/**
* @param key - The key whose first value to retrieve
* @returns The first value associated with the key.
* @param value - The value whose key to retrieve.
* @returns The key associated with the value.
*/
getValue(key: K): V | undefined;
getKey(value: V): K | undefined;

/**
* @returns An array of all values, for all keys.
*/
getAllValues(): V[];
getAll(): V[];

/**
* @param key - The key whose values to retrieve.
* @returns An array of all values associated with the key.
*/
getAllValuesFor(key: K): V[];
getAllFor(key: K): V[];
};
Loading

0 comments on commit 13bbec1

Please sign in to comment.