feat: address sorter (#13)

This commit is contained in:
Vasco Santos 2020-11-16 15:03:20 +01:00 committed by GitHub
parent 301c63a91e
commit cb5e71644b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 137 additions and 0 deletions

40
API.md
View File

@ -1,5 +1,9 @@
# API
* [addressSort.publicAddressesFirst(addresses)](#addresssortpublicaddressesfirstaddresses)
* [Parameters](#parameters)
* [Returns](#returns)
* [Example](#example)
* [arrayEquals(a, b)](#arrayequalsa-b)
* [Parameters](#parameters)
* [Returns](#returns)
@ -21,6 +25,42 @@
* [Returns](#returns-4)
* [Example](#example-4)
## addressSort.publicAddressesFirst(addresses)
Sort given addresses by putting public addresses first. In case of equality, a certified address will come first.
### Parameters
| Name | Type | Description |
|------|------|-------------|
| addresses | `Array<Address>` | Array of AddressBook addresses |
### Returns
| Type | Description |
|------|-------------|
| `Array<Address>` | returns array of sorted addresses |
### Example
```js
const multiaddr = require('multiaddr')
const { publicAddressesFirst } = require('libp2p-utils/src/address-sort')
const addresses = [
{
multiaddr: multiaddr('/ip4/127.0.0.1/tcp/4000'),
isCertified: false
},
{
multiaddr: multiaddr('/ip4/30.0.0.1/tcp/4000'),
isCertified: false
}
]
const sortedAddresses = publicAddressesFirst(addresses)
```
## arrayEquals(a, b)
Verify if two arrays of non primitive types with the "equals" function are equal.

44
src/address-sort.js Normal file
View File

@ -0,0 +1,44 @@
'use strict'
const isPrivate = require('./multiaddr/is-private')
/**
* Compare function for array.sort().
* This sort aims to move the private adresses to the end of the array.
* In case of equality, a certified address will come first.
*
* @param {Address} a
* @param {Address} b
* @returns {number}
*/
function addressesPublicFirstCompareFunction (a, b) {
const isAPrivate = isPrivate(a.multiaddr)
const isBPrivate = isPrivate(b.multiaddr)
if (isAPrivate && !isBPrivate) {
return 1
} else if (!isAPrivate && isBPrivate) {
return -1
}
// Check certified?
if (a.isCertified && !b.isCertified) {
return -1
} else if (!a.isCertified && b.isCertified) {
return 1
}
return 0
}
/**
* Sort given addresses by putting public addresses first.
* In case of equality, a certified address will come first.
*
* @param {Array<Address>} addresses
* @returns {Array<Address>}
*/
function publicAddressesFirst (addresses) {
return [...addresses].sort(addressesPublicFirstCompareFunction)
}
module.exports.publicAddressesFirst = publicAddressesFirst

53
test/address-sort.spec.js Normal file
View File

@ -0,0 +1,53 @@
'use strict'
/* eslint-env mocha */
const { expect } = require('aegir/utils/chai')
const multiaddr = require('multiaddr')
const { publicAddressesFirst } = require('../src/address-sort')
describe('address-sort', () => {
it('should sort public addresses first', () => {
const addresses = [
{
multiaddr: multiaddr('/ip4/127.0.0.1/tcp/4000'),
isCertified: false
},
{
multiaddr: multiaddr('/ip4/30.0.0.1/tcp/4000'),
isCertified: false
},
{
multiaddr: multiaddr('/ip4/31.0.0.1/tcp/4000'),
isCertified: false
}
]
const sortedAddresses = publicAddressesFirst(addresses)
expect(sortedAddresses[0].multiaddr.equals(multiaddr('/ip4/30.0.0.1/tcp/4000'))).to.eql(true)
expect(sortedAddresses[1].multiaddr.equals(multiaddr('/ip4/31.0.0.1/tcp/4000'))).to.eql(true)
expect(sortedAddresses[2].multiaddr.equals(multiaddr('/ip4/127.0.0.1/tcp/4000'))).to.eql(true)
})
it('should sort public certified addresses first', () => {
const addresses = [
{
multiaddr: multiaddr('/ip4/127.0.0.1/tcp/4000'),
isCertified: false
},
{
multiaddr: multiaddr('/ip4/30.0.0.1/tcp/4000'),
isCertified: false
},
{
multiaddr: multiaddr('/ip4/31.0.0.1/tcp/4000'),
isCertified: true
}
]
const sortedAddresses = publicAddressesFirst(addresses)
expect(sortedAddresses[0].multiaddr.equals(multiaddr('/ip4/31.0.0.1/tcp/4000'))).to.eql(true)
expect(sortedAddresses[1].multiaddr.equals(multiaddr('/ip4/30.0.0.1/tcp/4000'))).to.eql(true)
expect(sortedAddresses[2].multiaddr.equals(multiaddr('/ip4/127.0.0.1/tcp/4000'))).to.eql(true)
})
})