代码克隆检测(Code Clone Detection)数据集BigCloneBench最新版的使用方法

2023-11-05

代码克隆检测(Code Clone Detection)是软件工程领域的一个重要方向,每年都有很多论文,其中很多论文都用到了BigCloneBench,这里简单总结一下这个数据集的使用,不得不吐槽一点:学术界的数据集和工具,易用性都太差了,发再多paper有啥用呢?只是在自己小圈子里自娱自乐,完全没有实际的impact和意义。

如果我们在google搜索bigclonebench,可以看到排名第一的就是一个GitHub上的repo:https://github.com/clonebench/BigCloneBench

这里:https://github.com/clonebench/BigCloneBench#bigclonebench-version-2-use-this-version

写得很清楚,建议大家使用Version 2,并且告诉我们说:

The latest BigCloneBench is distributed with BigCloneEval here. It is significantly larger than the ERA version, and is distributed as a h2database file with a much simpler schema. If you need the full BigCloneBench, with all the validation artifacts, please contact us and we can arrange to send you a copy (it is quite large).

IJaDataset with the expanded files is available here: IJaDataset 2.0 + BigCloneBench Samples.

BigCloneBench full database (postgresql) is available here: BigCloneBench_Postgresql.

吐槽一下啊,到底是使用BigCloneEval呢,还是使用下面这个postgresql的文件呢,后面我们会看到,这两者也是不一样的。不得不说,很多Repo的ReadME的可读性都太差了。不过既然说了最新版的是连同BigCloneEval发布的,所以我们暂时下这个版本:

https://github.com/jeffsvajlenko/BigCloneEval

我刚看到这个项目也是一脸懵逼,一上来介绍:

BigCloneEval is a framework for performing clone detection tool evaluation experiments with the BigCloneBench clone benchmark.

然后就开始讲怎么安装了。呵呵呵,如果不了解的人看到这里会莫名其妙,为啥我要用一个framework来做evaluation呢?相信很多朋友和我的目的一样,都是需要把BigCloneBench下载下来训练及评价自己的模型,仅此而已,你不是应该先讲数据集怎么用,然后如果别人关心的话,再介绍自己的工具吗?况且也没介绍清楚。耐着性子往下看,看到Step 2,Step 3分别需要下载最新的BigCloneBench和IJaDataset,后面这个又是什么鬼?

https://www.dropbox.com/s/z2k8r78l63r68os/BigCloneBench_BCEvalVersion.tar.gz?dl=0

https://www.dropbox.com/s/xdio16u396imz29/IJaDataset_BCEvalVersion.tar.gz?dl=0

耐着性子把这些步骤做完,看到后面:

To evaluate the recall of a clone detection tool you must complete the following steps:

  1. Register the clone detection tool with BigCloneEval.
  2. Detect clones in IJaDataset using the clone detection tool.
  3. Import the detected clones into BigCloneEval.
  4. Configure and execution the evaluation experiment.

These steps are performed using BigCloneEval's commands, which are located in the command/ directory as scripts. These scripts must be executed from within the command directory (the command directory must be the working directory).

大概明白了,这个BigCloneEval是一个evaluation的framework,我们如果想使用这个framework评价自己的工具或者模型,需要注册(Register)自己的clone detection tool,但是这里完全不讲怎么注册自己的工具,当然,你可以认为这里给出了例子:

./registerTool -n "NiCad" -d "Default configuration"

但是,如果对这个不了解,鬼知道怎么注册自己的工具,鬼知道这个NiCad是什么东西?

呵呵呵,还是那句话,这些ReadME写得都太垃圾了。但是我们需要使用人家的数据集,只好从自己的角度来猜猜是怎么回事了。按照前面说的,Step 2中下载的压缩包BigCloneBench_BCEvalVersion.tar.gz,解压以后是bcb.h2.db和bcb.trace.db,按照Step 2中的提示,

Extract the contents of BigCloneBench (BigCloneBench_BCEvalVersion.tar.gz) into the 'bigclonebenchdb' directory of the BigCloneEval distribution.

可以预期,这两个(bcb.h2.db和bcb.trace.db)是这个版本的BigCloneBench的h2数据库文件。另外Step 3中,IJaDataset_BCEvalVersion.tar.gz解压以后是一个名为“bcb_reduced”的文件夹,需要:

Extract the contents of IJaDataset (IJaDataset_BCEvalVersion.tar.gz) into the 'ijadataset' directory of the BigCloneEval distribution.

所以这两步就是把相关的数据放到BigCloneEval的对应文件夹下,可以猜想这两部分就是主要的数据了。那么我们要使用BigCloneBench,只要关注这两步中的文件即可。

所以,第一步先用h2把这个数据库文件打开来看看,在这个页面:https://www.h2database.com/html/main.html

中下载All Platforms (zip, 8 MB)

发现解压之后是传统的Java软件目录,在bin目录下有JAR包,我们运行:

java -jar h2-1.4.200.jar

即可以通过浏览器打开数据库页面了。那么问题又来了,我们怎么把bcb.h2.db这样的文件导入数据库呢,搜索了一下,看到这里有人介绍:

https://stackoverflow.com/questions/46000726/tool-to-view-test-h2-db-h2-database

需要指定一下db文件相对于主文件夹的位置,ubuntu系统中就是/home/%用户名%/,简单起见,我就把上面的bcb.h2.db放到主文件夹下了,然后启动h2,在启动后的web界面中的JDBC URL填写:

jdbc:h2:~/bcb

点击connect后就可以看到这个数据库中的表了。例如我们执行:

SELECT * FROM CLONES;

就可以看到类似下面的数据记录:

这个嘛,应该就是表示clone关系了吧,但具体哪一列表示clone呢,尝试一下:

SELECT count(*) FROM CLONES where functionality_id=4;

结果是:4664949,如果我们执行:

SELECT count(*) FROM CLONES where functionality_id=3;

结果是:891777,如果执行:

SELECT count(*) FROM CLONES where functionality_id=2;

结果是:409962,而id=1的时候呢,结果是0,感觉这个比例和我看过的论文里的比例差不多,所以盲猜这个functionality_id表示的就是Type-1到Type-4的Clone。

(2021年1月28日更新:简单分析了之后,发现这个functionality_id并不是表示Type 1到4的Clone,而是SYNTACTIC_TYPE表示Clone类型,例如我们运行:

SELECT count(*) FROM CLONES where SYNTACTIC_TYPE=1

得到结果是48116,

SYNTACTIC_TYPE=2的时候是4234,SYNTACTIC_TYPE=3的时候是8531803,SYNTACTIC_TYPE=4的时候是0,所有的clone pair是8584153,sigh,看来之前的盲猜果然猜错了啊)

姑且这么认为吧(使用大部分数据集的时候基本靠猜,我也是醉了,学术界就是这么的低效)。相信function_id这些对应的就是表FUNCTION里的内容了。我们运行:

SELECT * FROM FUNCTIONS;

得到下面这张表:

这个很明显就是function信息了,如果我们先运行:

SELECT count(*) FROM FUNCTIONS;

得到的结果是:22285855,有两千多万个function?我表示很怀疑啊。那怎么将这些function和源码对应起来呢,就想到了bcb_reduced,在ubuntu中查看其属性,发现有:55,671 项,共 607.3 MB,我就说这个数据集肯定没有那么多function啊。简单浏览了一下这个文件夹,我们以/bcb_reduced/2/selected/145.java(这个目录下的第一个文件为例):

SELECT * FROM FUNCTIONS where name='145.java';

可以得到下面的结果:

而我们看一下145.java的内容:

package edu.harvard.iq.safe.saasystem.util;

import java.util.*;
import java.util.logging.*;
import java.io.*;
import javax.xml.stream.*;
import javax.xml.stream.events.XMLEvent;
import java.net.*;
import java.util.concurrent.*;

/**
 *
 * @author asone
 */
public class PLNConfigurationFileReader {

    static final Logger logger = Logger.getLogger(PLNConfigurationFileReader.class.getName());

    /**
     *
     * @param url
     * @param propertyName
     * @return
     */
    public static CopyOnWriteArraySet<String> read(URL url, String propertyName) {
        if ((propertyName == null) || (propertyName.equals(""))) {
            return null;
        }
        CopyOnWriteArraySet<String> peers = new CopyOnWriteArraySet<String>();
        XMLInputFactory xmlif = XMLInputFactory.newInstance();
        xmlif.setProperty("javax.xml.stream.isCoalescing", java.lang.Boolean.TRUE);
        xmlif.setProperty("javax.xml.stream.isNamespaceAware", java.lang.Boolean.TRUE);
        XMLStreamReader xmlr = null;
        BufferedInputStream stream = null;
        long starttime = System.currentTimeMillis();
        logger.info("Starting to parse the remote config xml[" + url + "]");
        int elementCount = 0;
        int topPropertyCounter = 0;
        int propertyTagLevel = 0;
        try {
            stream = new BufferedInputStream(url.openStream());
            xmlr = xmlif.createXMLStreamReader(stream, "utf8");
            int eventType = xmlr.getEventType();
            String curElement = "";
            String targetTagName = "property";
            String peerListAttrName = propertyName;
            boolean sentinel = false;
            boolean valueline = false;
            while (xmlr.hasNext()) {
                eventType = xmlr.next();
                switch(eventType) {
                    case XMLEvent.START_ELEMENT:
                        curElement = xmlr.getLocalName();
                        if (curElement.equals("property")) {
                            topPropertyCounter++;
                            propertyTagLevel++;
                            int count = xmlr.getAttributeCount();
                            if (count > 0) {
                                for (int i = 0; i < count; i++) {
                                    if (xmlr.getAttributeValue(i).equals(peerListAttrName)) {
                                        sentinel = true;
                                    }
                                }
                            }
                        }
                        if (sentinel && curElement.equals("value")) {
                            valueline = true;
                            String ipAd = xmlr.getElementText();
                            peers.add(ipAd);
                        }
                        break;
                    case XMLEvent.CHARACTERS:
                        break;
                    case XMLEvent.ATTRIBUTE:
                        if (curElement.equals(targetTagName)) {
                        }
                        break;
                    case XMLEvent.END_ELEMENT:
                        if (xmlr.getLocalName().equals("property")) {
                            if (sentinel) {
                                sentinel = false;
                                valueline = false;
                            }
                            elementCount++;
                            propertyTagLevel--;
                        } else {
                        }
                        break;
                    case XMLEvent.END_DOCUMENT:
                }
            }
        } catch (MalformedURLException ue) {
            logger.log(Level.WARNING, "specified url was not correct", ue);
        } catch (IOException ex) {
            logger.log(Level.WARNING, "remote config file cannot be read due IO problems", ex);
        } catch (XMLStreamException ex) {
            logger.log(Level.WARNING, "remote config file (" + url + ") cannot be read due to unexpected processing conditions", ex);
        } finally {
            if (xmlr != null) {
                logger.info("closing the xml stream reader");
                try {
                    xmlr.close();
                } catch (XMLStreamException ex) {
                }
            }
            if (stream != null) {
                logger.info("closing the stream");
                try {
                    stream.close();
                } catch (IOException ex) {
                }
            }
        }
        return peers;
    }
}

明显只能和最后一个记录对应起来啊(StartLine和EndLine分别是25和115),所以FUNCTION这个表里面,我们只需要关心Type为Selected这些记录即可。剩下的工作就是,需要把bcb_reduced这个文件夹中的源码都处理一下,提取出function,我记得之前也看到一篇博客说这个事情:https://www.cnblogs.com/xiaojieshisilang/p/10219344.html

呵呵呵呵呵,从恢复数据,到理解/处理数据,都得靠猜和自己摸索,再吐槽一遍:学术界的大部分工具和数据集都太垃圾了!!!

另外,由于我有Uderstand,所以从Java代码中提取function并确定其起始行号,是非常简单的事情,需要写一些代码,就能使用这个所谓的数据集了。相信绝对不是我一个人有这些感想,真的很无语。也希望我这个探索过程能帮助到一些有需求的朋友。

最后发两个链接,说明并不是我一个人有这样的疑问:

https://bbs.csdn.net/topics/396147037

https://github.com/jeffsvajlenko/BigCloneEval/issues/26

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代码克隆检测(Code Clone Detection)数据集BigCloneBench最新版的使用方法 的相关文章

  • 购买服务器及宝塔部署环境指南

    服务器购买宝塔部署环境指南 为什么程序员都需要一个自己的服务器 作为一个程序员 必须要发布自己的网站和项目 联系linux 自己的远程长裤 远程数据库 远程tomcat 搭建在服务器上 练习 Linux进行任意的环境部署操作 Window下
  • Spring Cloud的断路器模式是什么?如何使用断路器?Spring Cloud的配置管理是怎样实现的?

    1 Spring Cloud的断路器模式是什么 如何使用断路器 Spring Cloud的断路器模式是一种应对微服务架构中潜在故障的解决方案 在微服务架构中 不同的服务相互依赖 当某个服务出现故障或响应缓慢时 可能会导致级联故障 影响整个系
  • ELK技术栈实践(一)

    通常 日志被分散的储存不同的设备上 如果你管理数十上百台服务器 你还在使用依次登录每台机器的传统方法查阅日志 这样是不是感觉很繁琐和效率低下 当务之急我们使用集中化的日志管理 例如 开源的syslog 将所有服务器上的日志收集汇总 集中化管
  • C语言中低位存放,C语言 大端小端存储解析以及判断方法

    当我们在C语言中查看数据在内存中的存储时 我们经常会发现一个很奇怪的现象 什么现象呢 例如下面这段代码 int main int i 1 return 0 数据在内存中的存放方式似乎和我们想象的顺序不太一样 在我们的常规认知不一样 在我们的

随机推荐

  • [UPC] 2021秋组队17

    目录 A Quality Adjusted Life Year B Gwen s Gift C Forest for the Trees D H Index E Driving Lanes F Treasure Spotting G Nei
  • 测试第一年

    2018年 无心插柳柳成荫 终于进入了软件测试这一行 经过各种磕磕绊绊 进入了一家不足五十人的小私企 工资待遇和工作环境都不算好甚至可以说是略差 但在合肥这座对应届生极其不友好的城市 能找到一家公司做自己想做的事情已实属不易 作为一名初出茅
  • VS_VS2015或者VS2017出现跳过:1或者Skiped:1

    问题如下 解决办法 把绿色的部分全部勾上即可解决问题
  • 事务回滚,同时记录异常信息

    事务回滚 同时记录异常信息 需求 实现原理 实现 1 依赖HTTP重新发送请求 2 开启新事务 插入异常信息 需求 在发生异常时 回滚对数据库的操作 同时在数据库中插入一条异常信息 实现原理 开启新的事务 进行异常信息的数据库操作 实现 1
  • Linux中重要的目录有哪些?分别有何作用?

    当我们学习Linux知识时 除了要学习各种各样的命令之外 我们还需要了解Linux各个目录的功能 那么Linux中重要的目录有哪些 在Linux系统中 有两个非常重要的目录 bin与sbin 接下来我们详细的介绍一下 Linux重要的目录分
  • [C++]访问者模式

    在访问者模式 Visitor Pattern 中 我们使用了一个访问者类 它改变了元素类的执行算法 通过这种方式 元素的执行算法可以随着访问者改变而改变 这种类型的设计模式属于行为型模式 根据模式 元素对象已接受访问者对象 这样访问者对象就
  • 计算机视觉领域不同的方向:目标识别、目标检测、语义分割等

    计算机视觉任务 图像分类 image classification 图像分类 根据图像的主要内容进行分类 数据集 MNIST CIFAR ImageNet 目标检测 object detection 给定一幅图像 只需要找到一类目标所在的矩
  • 计算机网络知识点总结——第五章传输层

    目录 一 传输层概述 二 UDP协议 三 TCP协议 TCP报文段首部格式 重点 TCP连接管理 TCP可靠传输 TCP流量控制 重点 TCP拥塞控制 重点 拥塞控制四种算法 一 传输层概述 只有主机之间才会有的层次 传输层的功能 传输层提
  • “惊群”,看看nginx是怎么解决它的

    在说nginx前 先来看看什么是 惊群 简单说来 多线程 多进程 linux下线程进程也没多大区别 等待同一个socket事件 当这个事件发生时 这些线程 进程被同时唤醒 就是惊群 可以想见 效率很低下 许多进程被内核重新调度唤醒 同时去响
  • eclipse 导出maven 项目关联jar 文件

    一 默认导出maven 项目所在的文件夹target dependency 1 打开控制台指令窗口cmd 2 切换到maven 项目所在pom xml 文件所在目录 我的项目目录所在地址 D j2ee Morning 3 执行mvn 项目指
  • Qt多线程的创建详解

    文章目录 一 摘要 1 线程基础 2 为什么要创建多线程 3 创建多线程的方法 二 继承于QObject线程的创建 1 项目创建 2 代码编写与实现 三 线程间数据的传递 1 通过外部变量 2 通过信号与槽机制 四 总结 一 摘要 1 线程
  • Mysql 事务锁

    一 InnoDB锁的类型 S行级共享锁 S锁简单理解就是 运行 select from l where id 1 innoDB就会对id 1的这行数据进行加S锁 X行级排它锁 对数据进行修改时 就会对修改的行加X锁 排它的意思就是 在同一时
  • 【路径规划】基于哈里斯鹰优化算法的栅格法路径规划 机器人路径规划【Matlab代码#20】

    文章目录 可更换其他算法 获取资源 请见文章第6节 资源获取 1 原始HHO算法 2 机器人路径规划环境创建 3 路径规划模型建立 4 部分代码展示 5 仿真结果展示 6 资源获取 可更换其他算法 获取资源请见文章第6节 资源获取 1 原始
  • 白盒测试 代码检查

    6 2 1 代码检查法 代码检查包括桌面检查 代码审查和走查等 主要检查代码和设计的一致性 代码对标准的遵循 可读性 代码逻辑表达的正确性 代码结构的合理性等方面 发现违背程序编写标准的问题 程序中不安全 不明确和模糊的部分 找出程序中不可
  • SpringMvc学习-5-Spring MVC 文件上传

    文件上传 需要加入commons fileupload包 maven项目加入依赖
  • 1.SCT15单片机(建keil C51工程)

    1 文件管理 与新建文件 在其中创建3个文件 user obj app user 存放主函数和公共文件 obj keil软件生成的文件 app 存放各种外设文件 2 新建工程 a 打开Keil软件 点击如下进入新建工程界面 b 点击开始新建
  • assert_param()函数

    我们在学STM32的时候函数assert param出现的几率非常大 上网搜索一下 网上一般解释断言机制 做为程序开发调试阶段时使用 下面我就谈一下我对这些应用的看法 学习东西抱着知其然也要知其所以然 4 断言机制函数assert para
  • Pycharm激活注意事项及问题解决

    Pycharm激活方式 推荐采用破解补丁激活 基本上可以是永久使用 破解补丁请自行百度 都可以找得到 破解注意事项 激活之前需要先以试用的形式先启动一次Pycharm 进入到编程界面即为算作一次 破解完成之后打不开Pycharm问题 此问题
  • 在ubuntu16.04上搭建svn服务器

    本文介绍在如何在ubuntu16 04 的系统上搭建svn服务器以及可能遇到的问题 下面的操作都以root用户进行 1 安装svn服务器软件subversion 安装完成后的svn版本为 1 9 3 通过svn version可以查看版本号
  • 代码克隆检测(Code Clone Detection)数据集BigCloneBench最新版的使用方法

    代码克隆检测 Code Clone Detection 是软件工程领域的一个重要方向 每年都有很多论文 其中很多论文都用到了BigCloneBench 这里简单总结一下这个数据集的使用 不得不吐槽一点 学术界的数据集和工具 易用性都太差了