2121
2222import org .apache .iotdb .common .rpc .thrift .TSStatus ;
2323import org .apache .iotdb .commons .executable .ExecutableManager ;
24+ import org .apache .iotdb .commons .executable .ReferenceCountedJarMetaKeeper ;
2425import org .apache .iotdb .commons .snapshot .SnapshotProcessor ;
2526import org .apache .iotdb .commons .udf .UDFInformation ;
2627import org .apache .iotdb .commons .udf .UDFTable ;
3738import org .apache .iotdb .rpc .TSStatusCode ;
3839import org .apache .iotdb .udf .api .exception .UDFManagementException ;
3940
40- import org .apache .tsfile .utils .ReadWriteIOUtils ;
4141import org .slf4j .Logger ;
4242import org .slf4j .LoggerFactory ;
4343
5050import java .nio .ByteBuffer ;
5151import java .util .ArrayList ;
5252import java .util .Collections ;
53- import java .util .HashMap ;
5453import java .util .List ;
5554import java .util .Map ;
5655import java .util .concurrent .locks .ReentrantLock ;
@@ -63,7 +62,7 @@ public class UDFInfo implements SnapshotProcessor {
6362 ConfigNodeDescriptor .getInstance ().getConf ();
6463
6564 private final UDFTable udfTable ;
66- private final Map < String , String > existedJarToMD5 ;
65+ private final ReferenceCountedJarMetaKeeper jarMetaKeeper ;
6766
6867 private final UDFExecutableManager udfExecutableManager ;
6968
@@ -73,7 +72,7 @@ public class UDFInfo implements SnapshotProcessor {
7372
7473 public UDFInfo () throws IOException {
7574 udfTable = new UDFTable ();
76- existedJarToMD5 = new HashMap <> ();
75+ jarMetaKeeper = new ReferenceCountedJarMetaKeeper ();
7776 udfExecutableManager =
7877 UDFExecutableManager .setupAndGetInstance (
7978 CONFIG_NODE_CONF .getUdfTemporaryLibDir (), CONFIG_NODE_CONF .getUdfDir ());
@@ -97,7 +96,8 @@ public void validate(String udfName, String jarName, String jarMD5)
9796 String .format ("Failed to create UDF [%s], the same name UDF has been created" , udfName ));
9897 }
9998
100- if (existedJarToMD5 .containsKey (jarName ) && !existedJarToMD5 .get (jarName ).equals (jarMD5 )) {
99+ if (jarMetaKeeper .containsJar (jarName )
100+ && !jarMetaKeeper .jarNameExistsAndMatchesMd5 (jarName , jarMD5 )) {
101101 throw new UDFManagementException (
102102 String .format (
103103 "Failed to create UDF [%s], the same name Jar [%s] but different MD5 [%s] has existed" ,
@@ -115,15 +115,15 @@ public void validate(String udfName) throws UDFManagementException {
115115 }
116116
117117 public boolean needToSaveJar (String jarName ) {
118- return ! existedJarToMD5 . containsKey (jarName );
118+ return jarMetaKeeper . needToSaveJar (jarName );
119119 }
120120
121121 public TSStatus addUDFInTable (CreateFunctionPlan physicalPlan ) {
122122 try {
123123 final UDFInformation udfInformation = physicalPlan .getUdfInformation ();
124124 udfTable .addUDFInformation (udfInformation .getFunctionName (), udfInformation );
125125 if (udfInformation .isUsingURI ()) {
126- existedJarToMD5 . put (udfInformation .getJarName (), udfInformation .getJarMD5 ());
126+ addJarReference (udfInformation .getJarName (), udfInformation .getJarMD5 ());
127127 if (physicalPlan .getJarFile () != null ) {
128128 udfExecutableManager .saveToInstallDir (
129129 ByteBuffer .wrap (physicalPlan .getJarFile ().getValues ()), udfInformation .getJarName ());
@@ -168,7 +168,10 @@ public JarResp getUDFJar(GetUDFJarPlan physicalPlan) {
168168 public TSStatus dropFunction (DropFunctionPlan req ) {
169169 String udfName = req .getFunctionName ();
170170 if (udfTable .containsUDF (udfName )) {
171- existedJarToMD5 .remove (udfTable .getUDFInformation (udfName ).getJarName ());
171+ final UDFInformation udfInformation = udfTable .getUDFInformation (udfName );
172+ if (udfInformation .isUsingURI ()) {
173+ removeJarReference (udfInformation .getJarName ());
174+ }
172175 udfTable .removeUDFInformation (udfName );
173176 }
174177 return new TSStatus (TSStatusCode .SUCCESS_STATUS .getStatusCode ());
@@ -181,7 +184,7 @@ public Map<String, UDFInformation> getRawUDFTable() {
181184
182185 @ TestOnly
183186 public Map <String , String > getRawExistedJarToMD5 () {
184- return existedJarToMD5 ;
187+ return jarMetaKeeper . getJarNameToMd5Map () ;
185188 }
186189
187190 @ Override
@@ -225,30 +228,39 @@ public void processLoadSnapshot(File snapshotDir) throws IOException {
225228 deserializeExistedJarToMD5 (fileInputStream );
226229
227230 udfTable .deserializeUDFTable (fileInputStream );
231+ rebuildJarMetadataFromUDFTable ();
228232 } finally {
229233 releaseUDFTableLock ();
230234 }
231235 }
232236
233237 public void serializeExistedJarToMD5 (OutputStream outputStream ) throws IOException {
234- ReadWriteIOUtils .write (existedJarToMD5 .size (), outputStream );
235- for (Map .Entry <String , String > entry : existedJarToMD5 .entrySet ()) {
236- ReadWriteIOUtils .write (entry .getKey (), outputStream );
237- ReadWriteIOUtils .write (entry .getValue (), outputStream );
238- }
238+ jarMetaKeeper .serializeJarNameToMd5 (outputStream );
239239 }
240240
241241 public void deserializeExistedJarToMD5 (InputStream inputStream ) throws IOException {
242- int size = ReadWriteIOUtils .readInt (inputStream );
243- while (size > 0 ) {
244- existedJarToMD5 .put (
245- ReadWriteIOUtils .readString (inputStream ), ReadWriteIOUtils .readString (inputStream ));
246- size --;
247- }
242+ jarMetaKeeper .deserializeJarNameToMd5 (inputStream );
248243 }
249244
250245 public void clear () {
251- existedJarToMD5 .clear ();
246+ jarMetaKeeper .clear ();
252247 udfTable .clear ();
253248 }
249+
250+ private void addJarReference (String jarName , String jarMD5 ) {
251+ jarMetaKeeper .addReference (jarName , jarMD5 );
252+ }
253+
254+ private void removeJarReference (String jarName ) {
255+ jarMetaKeeper .removeReference (jarName );
256+ }
257+
258+ private void rebuildJarMetadataFromUDFTable () {
259+ jarMetaKeeper .clear ();
260+ for (UDFInformation udfInformation : udfTable .getAllNonBuiltInUDFInformation ()) {
261+ if (udfInformation .isUsingURI ()) {
262+ addJarReference (udfInformation .getJarName (), udfInformation .getJarMD5 ());
263+ }
264+ }
265+ }
254266}
0 commit comments