Closed kyranet closed 6 years ago
The example of using set in this is completely useless because Array already removes/adds by default, which is the equivalent to using new Set(). As for map you have issues:
Set#has()
is faster than most methods for Array. And there can never be two entries with the same value (like in Array) but it benefits on how easy it is to use. SettingGateway would build an instance of Set
instead of Array
when the key requires a Set
.ValueController
, not for the proposal itself, although that can be handled, it's up to the developer to not do such practises.For example, the following Map instance:
Map { '224236171838881792' => { colour: 'red', animal: 'dog' } }
Is stored into a JSON db as:
[
['224236171838881792', { colour: 'red', animal: 'dog' }]
]
Then if you pass the array above into new Map()
, you'll get the first map. And it does not have a property of id
, instead, it's mapped by a key that serves as id.
Why can't you just do an object instead of map then
{
'224236171838881792': { somedata }
}
And again, Array already does what Set does (only having one key of whatever) along with the ability to duplicate entries as well, don't think there's a reason you need to have functionality in both, so Array default adding/removing should probably be removed
More edits because im stupid and i don't think my comments through: It's also probably more performant to do an object type instead of map, considering once you parse the returned JSON you will have your object, instead of having to also iterate through that entire array just to get the items set in the map
Because that requires the iteration of an object's keys with Object.keys()
which performance is 27 times lower than iterating an array by index. Building so many Configuration
instances and needing to run Object.keys
in one or more keys in every single one of them may result on a slow startup.
Outside performance, it's a pain for TypeScript users to handle that, and it's also an antipattern, it should not be made.
TypeScript has no bearing on this conversation. realistically this is only going to be used by Javascript users.
It's already going to be taxing on performance and startup for having to iterate over the parsed array to create the map.
It's also going to create a new interface that will be more ambiguous compared to the other ones
<Config>.someMapKey.get() /* <-- having to use a function to get the data rather then */
<Config>.someObjectKey["Object"]
<Config>.someArrayKey[0]
<Config>.someString
Nonetheless, I do think a "Type" Vault is necessary so custom types are easier to add.
It's not taxing on performance if the array is empty, which it's the case for the 50% of cases. new Map()
doesn't iterate the array if it's empty. Unlike your idea of an object, that needs to run an expensive function (which filters ~7 built-in properties of Object
, so it always has keys to iterate).
Not to mention that when you add/remove a property from an object, you are rebuilding it from scratch, so, it's an incredibly bad idea, and remember that we have discussed about this in Komada 0.20.0 development. This behavior does not happen in a Map as it's a collection of key/value designed to have a variable amount of entries, which objects aren't (due to their nature of immutability).
What you're proposing is much more taxing than my proposal in both CPU and RAM, as well as it contains antipatterns that seriously affect the performance in V8, it's all based on program optimization.
EDIT:
A "type" vault is exactly the type any
. it allows any type, with no restrictions, the multiValue
doesn't wrap the data from the DB into an array unless told so, what it does is wrap that data in a different constructor, such as Map
, Set
, Array
or a custom one.
Describe the proposal
Since SGv1, in the PR #255 from Komada, we had the first implementation of
SchemaPiece
being able to store more than a single value of the same type (instead of being type array, from the former configuration system).However, this system is extremely old and should be renamed and refactored into something much better, in this proposal, I'll use
SchemaPiece#multiValue
as a placeholder for a better name.What does
SchemaPiece#multiValue
do compared toSchemaPiece#array
? The current name limits the options, the values may be contained inside an array or not, but, what if I want to useSet
orMap
? The current system does not allow it, but multiValue will.Implementation
There are multiple ways to achieve this, but I'll present two in this proposal:
ValueController
This is more versatile, it allows custom types and moves some of the heavy work from SG to them, it also allows users to implement their own
ValueController
, for example, one beingCollection
extendingMap
and so on. Compatibility withstring
for simplicity inSchemaFolderAddOptions
is accepted with a later resolve.Said
ValueController
would implement basic methods such ascreate
,clone
,add
,remove
andmodify
and they could be stored inGatewayDriver
together with the available key types.Internal Resolving
This is less customizable and more hardcoded, plus makes SettingGateway's internals much heavier. These methods would be integrated in a different file (similar to a util) for later usage.
In both options, you'll be able to do
And the new values will be stored in the Map. However, some of the multiValue may not be able to be directly configurable, so they'll have the same behavior as
type: 'any'
: setsSchemaPiece#configurable
to false.