1
1
package org.phpinnacle.toblerone
2
2
3
+ import org.apache.kafka.common.cache.LRUCache
4
+ import org.apache.kafka.common.cache.SynchronizedCache
3
5
import org.apache.kafka.common.config.ConfigDef
4
6
import org.apache.kafka.connect.connector.ConnectRecord
5
7
import org.apache.kafka.connect.data.Schema
@@ -30,6 +32,8 @@ abstract class RadixTransform<R : ConnectRecord<R>?> : Transformation<R> {
30
32
)
31
33
32
34
private const val PURPOSE = " base-convert-transform"
35
+
36
+ private val cache = SynchronizedCache (LRUCache <Schema , Schema >(16 ))
33
37
}
34
38
35
39
private lateinit var fields: Map <String , Int >
@@ -76,30 +80,20 @@ abstract class RadixTransform<R : ConnectRecord<R>?> : Transformation<R> {
76
80
val value = Requirements .requireStruct(operatingValue(record), PURPOSE )
77
81
val schema = operatingSchema(record) ? : return record
78
82
79
- val outputValues = mutableMapOf< String , Any >( )
80
- val outputSchema = SchemaUtil .copySchemaBasics(schema )
83
+ val outputSchema = copySchema(schema )
84
+ val outputValues = Struct (outputSchema )
81
85
82
86
for (field in schema.fields()) {
83
87
val name = field.name()
84
88
85
- if (name !in fields.keys) {
86
- outputValues[name] = value.get(field)
87
- outputSchema.field(name, field.schema())
88
-
89
- continue
89
+ if (name in fields.keys) {
90
+ outputValues.put(name, convert(name, field.schema(), value))
91
+ } else {
92
+ outputValues.put(name, value.get(field))
90
93
}
91
-
92
- val (newSchema, newValue) = convert(name, field.schema(), value)
93
-
94
- outputSchema.field(name, newSchema)
95
- outputValues[name] = newValue
96
94
}
97
95
98
- val outputStruct = Struct (outputSchema)
99
-
100
- outputValues.forEach { outputStruct.put(it.key, it.value) }
101
-
102
- return newRecord(record, outputSchema.schema(), outputStruct)
96
+ return newRecord(record, outputSchema.schema(), outputValues)
103
97
}
104
98
105
99
private fun convert (key : String , value : Any ): Any {
@@ -114,19 +108,55 @@ abstract class RadixTransform<R : ConnectRecord<R>?> : Transformation<R> {
114
108
}
115
109
}
116
110
117
- private fun convert (key : String , schema : Schema , value : Struct ): Pair < Schema , Any > {
118
- val radix = fields[key] ? : return Pair (schema, value)
111
+ private fun convert (key : String , schema : Schema , value : Struct ): Any {
112
+ val radix = fields[key] ? : return value
119
113
120
114
return when (schema.type()) {
121
- Schema .Type .INT8 -> Pair (Schema .STRING_SCHEMA , value.getInt16(key).toString(radix))
122
- Schema .Type .INT16 -> Pair (Schema .STRING_SCHEMA , value.getInt16(key).toString(radix))
123
- Schema .Type .INT32 -> Pair (Schema .STRING_SCHEMA , value.getInt32(key).toString(radix))
124
- Schema .Type .INT64 -> Pair (Schema .STRING_SCHEMA , value.getInt64(key).toString(radix))
125
- Schema .Type .STRING -> Pair (Schema .INT32_SCHEMA , value.getString(key).trim().toInt(radix))
126
- else -> Pair (schema, value)
115
+ Schema .Type .INT8 -> value.getInt16(key).toString(radix)
116
+ Schema .Type .INT16 -> value.getInt16(key).toString(radix)
117
+ Schema .Type .INT32 -> value.getInt32(key).toString(radix)
118
+ Schema .Type .INT64 -> value.getInt64(key).toString(radix)
119
+ Schema .Type .STRING -> value.getString(key).trim().toInt(radix)
120
+ else -> value
121
+ }
122
+ }
123
+
124
+ private fun infer (schema : Schema ): Schema {
125
+ return when (schema.type()) {
126
+ Schema .Type .INT8 -> Schema .STRING_SCHEMA
127
+ Schema .Type .INT16 -> Schema .STRING_SCHEMA
128
+ Schema .Type .INT32 -> Schema .STRING_SCHEMA
129
+ Schema .Type .INT64 -> Schema .STRING_SCHEMA
130
+ Schema .Type .STRING -> Schema .INT32_SCHEMA
131
+ else -> schema
127
132
}
128
133
}
129
134
135
+ private fun copySchema (schema : Schema ): Schema
136
+ {
137
+ val cached = cache.get(schema)
138
+
139
+ if (cached != null ) {
140
+ return cached
141
+ }
142
+
143
+ val output = SchemaUtil .copySchemaBasics(schema)
144
+
145
+ for (field in schema.fields()) {
146
+ val name = field.name()
147
+
148
+ if (name in fields.keys) {
149
+ output.field(name, infer(field.schema()))
150
+ } else {
151
+ output.field(name, field.schema())
152
+ }
153
+ }
154
+
155
+ cache.put(schema, output)
156
+
157
+ return output
158
+ }
159
+
130
160
class Key <R : ConnectRecord <R >? > : RadixTransform <R >() {
131
161
override fun operatingSchema (record : R ? ): Schema ? = record?.keySchema()
132
162
0 commit comments