Skip to content
代码片段 群组 项目
提交 e73960c9 编辑于 作者: Timotej Ecimovic's avatar Timotej Ecimovic
浏览文件

Add topological sort to deal with the struct dependencies.

上级 136cfcb8
No related branches found
No related tags found
无相关合并请求
...@@ -5563,9 +5563,9 @@ ...@@ -5563,9 +5563,9 @@
} }
}, },
"tar": { "tar": {
"version": "6.1.0", "version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"requires": { "requires": {
"chownr": "^2.0.0", "chownr": "^2.0.0",
"fs-minipass": "^2.0.0", "fs-minipass": "^2.0.0",
...@@ -9667,9 +9667,9 @@ ...@@ -9667,9 +9667,9 @@
} }
}, },
"tar": { "tar": {
"version": "6.1.0", "version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"dev": true, "dev": true,
"requires": { "requires": {
"chownr": "^2.0.0", "chownr": "^2.0.0",
...@@ -13139,9 +13139,9 @@ ...@@ -13139,9 +13139,9 @@
} }
}, },
"tar": { "tar": {
"version": "6.1.0", "version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"dev": true, "dev": true,
"requires": { "requires": {
"chownr": "^2.0.0", "chownr": "^2.0.0",
...@@ -20257,9 +20257,9 @@ ...@@ -20257,9 +20257,9 @@
} }
}, },
"jszip": { "jszip": {
"version": "3.6.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz",
"integrity": "sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==", "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==",
"dev": true, "dev": true,
"requires": { "requires": {
"lie": "~3.3.0", "lie": "~3.3.0",
...@@ -21576,9 +21576,9 @@ ...@@ -21576,9 +21576,9 @@
} }
}, },
"tar": { "tar": {
"version": "6.1.0", "version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"dev": true, "dev": true,
"requires": { "requires": {
"chownr": "^2.0.0", "chownr": "^2.0.0",
...@@ -22562,9 +22562,9 @@ ...@@ -22562,9 +22562,9 @@
"dev": true "dev": true
}, },
"path-parse": { "path-parse": {
"version": "1.0.6", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true "dev": true
}, },
"path-to-regexp": { "path-to-regexp": {
...@@ -26995,6 +26995,11 @@ ...@@ -26995,6 +26995,11 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
}, },
"toposort": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
"integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA="
},
"totalist": { "totalist": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz",
...@@ -27697,9 +27702,9 @@ ...@@ -27697,9 +27702,9 @@
} }
}, },
"url-parse": { "url-parse": {
"version": "1.5.1", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"querystringify": "^2.1.1", "querystringify": "^2.1.1",
...@@ -102,6 +102,7 @@ ...@@ -102,6 +102,7 @@
"request": "^2.88.2", "request": "^2.88.2",
"source-map-support": "^0.5.19", "source-map-support": "^0.5.19",
"sqlite3": "^5.0.2", "sqlite3": "^5.0.2",
"toposort": "^2.0.2",
"utf-8-validate": "^5.0.5", "utf-8-validate": "^5.0.5",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"ws": "^7.5.2", "ws": "^7.5.2",
......
...@@ -206,6 +206,7 @@ async function selectAllStructsWithItems(db, packageId) { ...@@ -206,6 +206,7 @@ async function selectAllStructsWithItems(db, packageId) {
db, db,
` `
SELECT SELECT
STRUCT.STRUCT_ID AS STRUCT_ID,
STRUCT.NAME AS STRUCT_NAME, STRUCT.NAME AS STRUCT_NAME,
ITEM.NAME AS ITEM_NAME, ITEM.NAME AS ITEM_NAME,
ITEM.FIELD_IDENTIFIER AS ITEM_IDENTIFIER, ITEM.FIELD_IDENTIFIER AS ITEM_IDENTIFIER,
...@@ -231,7 +232,9 @@ ORDER BY STRUCT.NAME, ITEM.FIELD_IDENTIFIER`, ...@@ -231,7 +232,9 @@ ORDER BY STRUCT.NAME, ITEM.FIELD_IDENTIFIER`,
if (acc.length == 0 || acc[acc.length - 1].name != value.STRUCT_NAME) { if (acc.length == 0 || acc[acc.length - 1].name != value.STRUCT_NAME) {
// Create a new object // Create a new object
objectToActOn = { objectToActOn = {
id: value.STRUCT_ID,
name: value.STRUCT_NAME, name: value.STRUCT_NAME,
label: value.STRUCT_NAME,
items: [], items: [],
} }
acc.push(objectToActOn) acc.push(objectToActOn)
......
...@@ -92,7 +92,7 @@ function zcl_structs(options) { ...@@ -92,7 +92,7 @@ function zcl_structs(options) {
let promise = templateUtil let promise = templateUtil
.ensureZclPackageId(this) .ensureZclPackageId(this)
.then((packageId) => .then((packageId) =>
queryZcl.selectAllStructsWithItemCount(this.global.db, packageId) queryZcl.selectAllStructsWithItems(this.global.db, packageId)
) )
.then((structs) => zclUtil.sortStructsByDependency(structs)) .then((structs) => zclUtil.sortStructsByDependency(structs))
.then((structs) => templateUtil.collectBlocks(structs, options, this)) .then((structs) => templateUtil.collectBlocks(structs, options, this))
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* *
* @module REST API: various zcl utilities * @module REST API: various zcl utilities
*/ */
const toposort = require('toposort')
/** /**
* Comparator for sorting clusters. * Comparator for sorting clusters.
...@@ -69,16 +70,51 @@ function commandComparator(a, b) { ...@@ -69,16 +70,51 @@ function commandComparator(a, b) {
return 0 return 0
} }
function findStructByName(structs, name) {
for (const s of structs) {
if (s.name == name) {
return s
}
}
return null
}
/** /**
* This method retrieves a bunch of structs sorted * This method retrieves a bunch of structs sorted
* alphabetically. It's expected to resort the structs into a list * alphabetically. It's expected to resort the structs into a list
* where they are sorted in a way where dependency is observed. * where they are sorted in a way where dependency is observed.
* *
* It uses the DFS algorithm to traverse the DAG in a way the
* dependencies are observed.
*
* @param {*} structs * @param {*} structs
* @returns * @returns
*/ */
async function sortStructsByDependency(structs) { async function sortStructsByDependency(structs) {
return structs let allStructNames = structs.map((s) => s.name)
let edges = []
// Add edges
structs.forEach((s) => {
s.items.forEach((i) => {
const type = i.type
if (allStructNames.includes(type)) {
edges.push([s.name, type])
}
})
})
let sortedEdges = toposort(edges).reverse()
let finalSort = []
sortedEdges.forEach((s) => {
finalSort.push(findStructByName(structs, s))
})
allStructNames.forEach((s) => {
if (!sortedEdges.includes(s)) finalSort.push(findStructByName(structs, s))
})
return finalSort
} }
exports.clusterComparator = clusterComparator exports.clusterComparator = clusterComparator
......
...@@ -86,4 +86,21 @@ limitations under the License. ...@@ -86,4 +86,21 @@ limitations under the License.
<item name="b" type="BOOLEAN" optional="false"/> <item name="b" type="BOOLEAN" optional="false"/>
<item name="c" type="SimpleStruct" optional="false"/> <item name="c" type="SimpleStruct" optional="false"/>
</struct> </struct>
<struct name="A">
<item name="x" type="UINT8U"/>
<item name="b" type="B"/>
<item name="c" type="C"/>
</struct>
<struct name="B">
<item name="x" type="UINT8U"/>
<item name="d" type="D"/>
</struct>
<struct name="C">
<item name="x" type="UINT8U"/>
</struct>
<struct name="D">
<item name="x" type="UINT8U"/>
<item name="c" type="C"/>
</struct>
</configurator> </configurator>
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册