ソフトウェアの類似性の分析とその応用に関する研究

Slides:



Advertisements
Similar presentations
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 保守支援を目的とした コードクローン情報検索ツール.
Advertisements

シーケンス図の生成のための実行履歴圧縮手法
背景 ソフトウェアの大規模化・複雑化 生産性と品質の向上 ↓ オブジェクト指向分析設計の適用 開発ツールの投入.
コードクローン履歴閲覧環境を用いたクローン評価の試み
TF-IDF法とLSHアルゴリズムを用いた 関数単位のコードクローン検出法
AGMアルゴリズムを用いた ギャップを含むコードクローン情報の生成
Object Group ANalizer Graduate School of Information Science and Technology, Osaka University OGAN visualizes representative interactions between a pair.
研究の背景 コードクローン ソースコード中に存在する一致または類似したコード片
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
川口真司 松下誠 井上克郎 大阪大学大学院情報科学研究科
Java ソフトウェア部品検索システム SPARS-J のための リポジトリ自動更新機能の実現
アイテムセットマイニングを利用した コードクローン分析作業の効率向上
プログラム実行時情報を用いたトランザクションファンクション抽出手法
大規模ソースコード集合を対象とした 類似関数集合群の抽出
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
コードクローン分析ツールGeminiを用いたコードクローン分析手順
ギャップを含むコードクローンの フィルタリング手法の提案
ソースコードの同時修正支援における関数クローン検出ツールの有効性調査
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
識別子の共起関係に基づく類似コード検索法の提案と 欠陥検出への適用
ソードコードの編集に基づいた コードクローンの分類とその分析システム
関数の変更履歴と呼出し関係に基づいた開発履歴理解支援システムの実現
コード片の生存期間がコードクローンと欠陥修正の有無に与える影響分析
潜在的意味解析法LSAに基づく ソフトウェアシステム分類法の提案
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
クローンセットに対する主要編集者の分析法の提案と調査
重複コードと非重複コードにおける 修正頻度の比較
Javaプログラムの変更を支援する 影響波及解析システム
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析
オープンソース開発支援のための ソースコード及びメールの履歴対応表示システム
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コード片のベクトル表現に基づく 大規模コードクローン集合の特徴調査
オープンソース開発支援のための リビジョン情報と電子メールの検索システム
コードの生存期間を考慮したコードクローンと欠陥修正の関係調査
コードクローンの動作を比較するためのコードクローン周辺コードの解析
コードクローンに対する一貫性のない変更に起因する欠陥の検出
Token Comparison Approach to Detect Code Clone-related Bugs
ソースコードの静的特性を用いた Javaプログラム間類似度測定ツールの試作
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
コードクローン編集者数に着目した開発履歴の分析
コードクローンのメトリクス値と 開発者の相関の調査
Geminiを用いた効果的なコードクローン分析方法
ソフトウェア保守のための コードクローン情報検索ツール
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
類似度メトリクスを用いた Javaソースコード間類似度測定ツールの試作
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
コーディングパターンの あいまい検索の提案と実装
コードクローン間の依存関係に基づく リファクタリング支援環境の実装
ソフトウェアプロダクト集合に対する 派生関係木の構築
潜在的意味解析法LSA を利用した ソフトウェア分類システムの試作
メトリクス値の変化に基づく コードクローンの編集傾向分析
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
保守請負時を対象とした 労力見積のためのメトリクスの提案
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
メソッドの同時更新履歴を用いたクラスの機能別分類法
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
容易に使用可能な grep風コードクローン検索ツール
ソフトウェア理解支援を目的とした 辞書の作成法
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
コードクローン解析に基づく デザインパターン適用候補の検出手法
回帰テストにおける実行系列の差分の効率的な検出手法
関数の変更履歴と呼び出し関係に 基づいた開発履歴理解支援システム
Geminiを用いた効果的なコードクローン分析方法
オブジェクト指向メトリクスを用いた 開発支援に関する研究 --- VC++とMFCを用いた開発を対象として ---
Presentation transcript:

ソフトウェアの類似性の分析とその応用に関する研究 大学院情報科学研究科 コンピュータサイエンス専攻 井上研究室 川口真司 2005/12/21

ソフトウェアリポジトリ インターネット ネットワーク上の開発基盤サービス ソースコードや ドキュメントなどの 管理を行う 開発中に発見した バグの管理を行う ネットワーク上の開発基盤サービス 大量のソフトウェア (SourceForge: 約 10 万 プロジェクト) 版管理システム バグ追跡システム ソフトウェアリポジトリ 一般ユーザ 開発者 近年、ネットワーク上で開発基盤環境を提供するソフトウェアリポジトリが急速に普及しています。 ソフトウェアリポジトは、ネットワークを通じてソースコードなどを管理する版管理システムをはじめ、バグ管理システムや掲示板、メーリングリスト管理システムなどのサービスを提供します。 たとえば、オープンソース開発における最大のソフトウェアリポジトリである SourceForge では約10万プロジェクトに対してサービスを提供しています。 また、その有用性から、社内プロジェクトの管理のために社内用ソフトウェアリポジトリを導入する企業も増えています。 掲示板 ML管理システム インターネット ユーザの要望等を 受け付ける 開発者間で行われた 議論を保存 2005/12/21

ソフトウェアの持つ類似性 膨大な数の成果物 成果物がもつ類似性とその活用 これまでに作成された大量のソフトウェア 大規模なソフトウェアに含まれる大量のコンポーネント、ソースコード 成果物がもつ類似性とその活用 類似の定義、発見 類似の応用 ソフトウェア 付属ドキュメントを用いて ソースコードを用いて ソフトウェアライブラリ 派生ソフトウェアの分類 コンポーネント 継承関係、利用関係、ソースコード等を用いて コンポーネントライブラリ ソフトウェアクラスタリング コード片 コードクローンに関する研究 クローン削除作業の支援、リファクタリング 2005/12/21

ソフトウェアの類似性 GURU (Maarek ら [46]) Ugurel らの手法 [62] SMMT (山本ら [64]) Unix の各コマンドを、man を利用して分類 IR メソッドを利用 Ugurel らの手法 [62] ソフトウェアに付随するドキュメントを利用して分類 support vector machine (SVM) を利用 SMMT (山本ら [64]) ソースコードそのものを直接用いて分類 CCFinder を利用 ソフトウェアライブラリの構築 [46, 62] 派生ソフトウェア群の分類 [64] 4.4BSD Lite から派生した、FreeBSD, NetBSD, OpenBSD の各バージョン間の類似度を比較 2005/12/21

コンポーネントの類似性 継承関係から (Spanoudakis ら *) 利用関係から (SPARS **) コンポーネントのソースコードに機械学習手法を適用 LSA(潜在的意味解析手法) を用いて (Maletic ら [47]) 自己組織化マップを用いて (Chan ら [15]) コンポーネントライブラリの構築 (SPARS **) ソフトウェアクラスタリング [47] ひとつのソフトウェアを、いくつかのコンポーネント群に分割 * Giorgos Spanoudakis, Panos Constantopoulos, Measuring Similarity Between Software Artifacts 1994, Proc. of the 6th International Conference on Software Engineering and Knowledge Engineering - SEKE '94, Jurmala, Latvia, June 1994. ** Katsuro Inoue, Reishi Yokomori, Tetsuo Yamamoto, Makoto Matsushita, Shinji Kusumoto, “Ranking Significance of Software Components Based on Use Relations”, IEEE Transactions on Software Engineering, Vol.31, No.3, pp.213-225 (2005) 2005/12/21

コード片の類似性 コードクローン クローン削除作業の支援 字句解析ベース [5, 6, 7, 11, 20, 33, 39, 40, 43, 53, 55] CCFinder (神谷ら [33] ) CloneDr (Baxter ら [11] ) メトリクスベース [8, 9, 10, 32, 49, 51] メソッド単位でメトリクスを定義 (Balazinskaら [8, 9, 10]) クローン削除作業の支援 コードクローンは保守工程における重大な障害のひとつ ある部分に修正が必要 → その部分のクローン全ての修正を検討 コードクローン分析環境 Gemini (植田ら *) リファクタリング支援 (肥後ら **) * 植田 泰士, 神谷 年洋, 楠本 真二, 井上 克郎, "開発保守支援を目指したコードクローン分析環境", 電子情報通信学会論文誌 D-I, Vol. J86-D-I, No. 12, pp. 863-871 (2003-12). ** 肥後 芳樹, 植田 泰士, 神谷 年洋, 楠本 真二, 井上 克郎, "コードクローン解析に基づくリファクタリングの試み", 情報処理学会論文誌, no. 45, vol. 5, pp. 1357-1366 (2004-5). 2005/12/21

ソフトウェアの持つ類似性 膨大な数の成果物 成果物がもつ類似性とその活用 これまでに作成された大量のソフトウェア 大規模なソフトウェアに含まれる大量のコンポーネント、ソースコード 成果物がもつ類似性とその活用 類似の定義、発見 類似の応用 ソフトウェア 付属ドキュメントを用いて ソースコードを用いて ソフトウェアライブラリ 派生ソフトウェアの分類 コンポーネント 継承関係、利用関係、ソースコード等を用いて コンポーネントライブラリ ソフトウェアクラスタリング コード片 コードクローンに関する研究 クローン削除作業の支援、リファクタリング 2005/12/21

論文の構成 第1章: まえがき 第2章: MUDABlue: ソフトウェアシステム自動分類手法 [1-1, 1-2, 1-3, 1-4] 第3章: 版管理システムを用いたクローン履歴抽出手法 [1-5] 第4章: むすび 2005/12/21

MUDABlue: ソフトウェア自動分類システム [2章] ソフトウェアそのものの分類の重要性 大量のソフトウェア → 分類、整理が必要 ML の議論や、掲示板やバグ追跡情報も有用 既存のソフトウェアライブラリ構築手法は不十分 分類先はあらかじめ用意する必要あり 分類結果は排他的 ドキュメントに依存 2005/12/21

MUDABlue の構成 ソフトウェア自動分類部 分類結果提示ユーザインタフェース 大量のソフトウェアを自動的に分類する 潜在的意味解析手法 LSA に基づく手法 自然言語文書の類似性を計測する手法 分類結果提示ユーザインタフェース キーワード検索、ディレクトリ型検索の両方をサポート Unifiable Cluster Map 手法による描画 (下3枚は削除の方向)、問題点は前の部分で指摘することろがあるので、そこで。 MUDABlue が備える三つの特徴をババンと オリジナルの目的のスライドは手ぬるい 2005/12/21

提案手法の特徴 階層構造も自動的に作成 非排他的な分類 ソースコードのみを用いて分類 カテゴリの作成には、さまざまなライブラリ・アーキテクチャに関する深い知識が必要 日々新しいカテゴリが誕生 非排他的な分類 ソフトウェアの分類には、複数個の基準が存在 ソフトウェアの用途 利用しているライブラリ、依存アーキテクチャ、等々 ソースコードのみを用いて分類 既存手法はソフトウェアに付属するドキュメントに基づいて分類 ドキュメントの量や質(特に均一性)に大きく依存 2005/12/21

非排他的分類 regexp エディタ 表計算 MFC GTK ソフトウェア1 ソフトウェア3 エディタ 表計算 GUI (MFC) 正規表現サポート (regexp) 正規表現サポート (regexp) ソフトウェア2 ソフトウェア4 エディタ 表計算 GUI (GTK) GUI (GTK) 正規表現サポート (regexp) 2005/12/21

潜在的意味解析法 LSA Latent Semantic Analysis [41, 42] 自然言語で書かれた文書、単語の類似度を計測する ベクトル空間モデルに従った手法の一つ ベクトル空間モデルでは検出できない間接的な関連の抽出を可能にしている 2005/12/21

LSA の例 単語ベクトル 文書ベクトル 文書間、単語間の類似度は ベクトル間の角度の cos や、 相関係数によって表す 文書1 文書4 2 3 4 5 6 A B C D E F G H A B B F G G 文書2 文書5 A B C D E F G H H 単語頻度行列を 作成 文書3 文書6 B C C C D E G H LSA 1 0.3 0.7 0.9 0.4 0.2 2 1.0 1.4 0.6 0.1 3 1.5 2.3 -0.2 4 0.0 5 6 -0.1 A B C D E F G H 2005/12/21

LSA の効果 間接的に関連している文書間の類似度も高い 文書間の類似度がより鮮明になる 文書間の相関係数行列 LSA適用前 LSA適用後 1 2 3 4 5 6 1.0 0.2 -0.1 -0.3 -0.5 0.5 -0.9 -0.2 -0.4 0.3 1 2 3 4 5 6 1.0 0.9 -0.6 -0.5 -0.8 -0.7 LSA適用前 LSA適用後 2005/12/21

識別子による分類 ソースコード中の識別子は、その動作を表している window という識別子があるプログラム文の周辺は、なんらかの GUI に関する操作を行っている 識別子のうち特に類似しているものを結びつけて、それらをひとつのグループとみなして分類を行う ソフトウェア1 ソフトウェア3 エディタ 表計算 GUI (MFC) GUI (MFC) window menuBar cmdButton window MFC 2005/12/21

提案手法(1/2) Sof1 Soft4 Soft1 Soft4 Soft2 Soft5 Soft2 Soft5 Soft3 Soft6 A B B F J G G I J Soft2 Soft5 Soft2 Soft5 1.トークン 抽出 A B C D E F G H H J Soft3 Soft6 Soft3 Soft6 B C C C D E G H J 2.共起行列の作成 1 2 3 4 5 6 A B C D E F G H I J 1 2 3 4 5 6 A B C D E F G H 3.孤立トークン, 普遍トークンの 削除 2005/12/21

提案手法(2/2) 4.LSA 5.トークン間の類似度計測、 クラスタ分析 ClusterName1 7.クラスタ 6.ソフトウェア 3 4 5 6 A B C D E F G H 1 0.3 0.7 0.9 0.4 0.2 2 1.0 1.4 0.6 0.1 3 1.5 2.3 -0.2 4 0.0 5 6 -0.1 A B C D E F G H 4.LSA 5.トークン間の類似度計測、 クラスタ分析 1 2 3 1 2 3 A B C D ClusterName1 F G H 7.クラスタ タイトルの 作成 6.ソフトウェア クラスタの 作成 1 4 5 6 1 4 5 6 ClusterName2 2005/12/21

ケーススタディ 実験を通じて以下のことを示す MUDABlue システムの実際のカテゴリ描画 抽出したカテゴリの評価 テストデータ 抽出カテゴリの概要 既存手法との適合率、再現率の比較 テストデータ SourceForge から無作為に選んだ 6 つのジャンル boardgames, compilers, database, editor, videoconversion, xterm 以上の 6 ジャンルに含まれる C プログラム 41 個 計 164,102 個の識別子 孤立トークン、普遍トークンを除く 22,048 識別子を LSA の入力として利用 2005/12/21

分類結果 40 個のカテゴリ ライブラリ、アーキテクチャに関するカテゴリの内訳 SourceForge のカテゴリに合致するカテゴリ 18 GTK(2 カテゴリ) GUI ライブラリ win32(3 カテゴリ) Windows32 API yacc 構文解析ライブラリ SSL SSL 通信用ライブラリ regexp 正規表現用ライブラリ getopt コマンドラインオプション読み取り用ライブラリ JNI Java Native Interface Python/C Python インタプリタ拡張用インタフェース SourceForge のカテゴリに合致するカテゴリ 18 ライブラリ、アーキテクチャに関するカテゴリ 11 はずれのカテゴリ 2005/12/21

適合率、再現率の評価 MUDABlue は既存の研究に対して同程度の信頼性を保っている GURU Ugurel らの手法 IR メソッドを利用 Unix の各コマンドを、man を利用して分類 Ugurel らの手法 support vector machine (SVM) を利用 ソフトウェアに付随するドキュメントに対して SVM を適用 MUDABlue は既存の研究に対して同程度の信頼性を保っている We evaluated retrieved categories by precision and recall. For comparison, the result of GURU and Ugurel’s method are also plotted. These researches categorize exclusive way and uses given category set. So MUDABlue and these researches are different and this comparison is not GENNMITU, but we can say that MUDABlue has same accuracy with these researches. 2005/12/21

考察 適合率、再現率は既存研究と同程度の水準を保っている MUDABlue は前提知識の入力が必要ない 非排他的な分類の実現 今後の課題 ドキュメントに依存しない 非排他的な分類の実現 今後の課題 「その他」カテゴリを減らす 識別子を選別する部分の改善が必要 カテゴリタイトルをよりわかりやすく 分かりやすいものもあれば、分かりにくいものも ライブラリに基づくカテゴリには分かりやすいタイトルがつく傾向 カテゴリの粒度をより適正に 細粒度にすぎる傾向 2005/12/21

クローン履歴分析手法 [3章] 既存のクローン抽出手法 過去に exact にコピーされた時点の状態を見れば明白 版管理システムが持つ履歴情報 版管理システムは、これまでにおこわなわれた変更の履歴を全て保持 過去の任意の時点のプロダクトを取得可能 2005/12/21

コードクローン コードクローン(あるいは単にクローン) クローンペア クローンセット 類似文字列が存在するコード片 クローンの位置は (ファイル名、開始行番号、終了行番号) で指定 クローンペア クローンA-1 とクローンA-2 が類似文字列であるときに、これらをクローンペアとよぶ クローンセット クローンペア関係において推移関係が成り立つクローンの集合 Clone A-1 Clone A-3 Clone A-2 Clone B-2 Clone B-1 2005/12/21

履歴を考慮したクローン分析 過去にクローン関係にあったコード片の抽出 過去の時点でのクローン解析情報 現在のクローンは、過去のどのクローンに対応するか? Clone A-3 追加 Clone A-3 Clone A-3 Clone A-1 Clone A-1 Clone A-1 Clone B-1 Clone B-1 Clone B-1 Clone A-4 Clone A-4, A-5 追加 Clone A-2 Clone A-2 Clone A-2 Clone B’-2 Clone B-5 Clone B’-2 Clone A-5 Clone B-2 Clone B-2 Clone B-2 Clone B’-1 Clone B-3 Clone B-4 Clone B’-3 Clone B’-1 Clone B’-3 Clone B-3, B-4, B-5 が編集 されて別クローンセットに Clone B’-3 削除 クローンセット B, B’ を 「分離クローンセット」と呼ぶ 2005/12/21

クローン履歴関係 (過去のコード片, 現在のコード片)のペア CCFinder によって発見されたクローンペア クローン履歴関係 ファイル1 ファイル1 挿入 Clone A Clone A Clone A クローン関係 ファイル2 ファイル2 CCFinder によって発見されたクローンペア Clone A Clone A ファイル3 削除 Clone B ファイル3 Clone B Clone B Vt-1 Vt 2005/12/21

クローン履歴関係抽出手法(1/2) 指定された期間 [0, t]、間隔Δt について期間 [0, t] を Δt ごとに分割、それぞれの時のファイルの状態をバージョン V0, V1, ..., Vt と表す 過去のプロダクトの取得には版管理システム (ex. cvs, subversion, ...) を用いる となりあうバージョン間について分析 V0, V1 をリポジトリから取得 V0, V1 間のクローン履歴関係を分析 Vt をリポジトリから取得 Vt-1, Vt 間を分析 ・・・ V0 V1 Vt-1 Vt 2005/12/21

クローン履歴関係抽出手法(2/2) 隣あうバージョン Vt-1, Vt について以下を行う クローン分析 クローン履歴関係分析 クローン分析には CCFinder を使用する クローンの行数、総行数に対する割合も計算 クローン履歴関係分析 HCt : バージョン間でクローン関係に変化のない履歴関係抽出 HAt: Vt において新規に追加されたクローンの履歴関係抽出 HTt: Vt において片方が削除されたクローンの履歴関係抽出 2005/12/21

2-1: クローン関係に変化のない履歴関係抽出 行番号 行番号 クローン 関係 ファイル1 ファイル1 7 Clone A 25 18 Clone A 31 HCt 37 クローン 履歴関係 43 Clone A ファイル2 ファイル2 HCt 22 22 Clone A 28 28 Clone A Vt の各クローンについて、Vt-1 の 「写像先」にクローンが存在す るかどうか検索 ファイル3 11 Clone B ファイル3 22 42 Clone B 48 写像先の決定には、編集操作による行番号のズレを考慮 Vt-1 Vt 2005/12/21

2-2: 追加されたクローンの履歴関係抽出 Vt-1 と 差分との間で CCFinder を適用 ファイル1 ファイル1 HAt Clone A Clone A クローン 履歴関係 Clone A HAt ファイル2 ファイル2 Clone A Clone A ファイル3 Clone B ファイル3 Clone B Vt-1 と 差分との間で CCFinder を適用 Vt-1 Vt 発見したクローンに対応する部分を履歴関係とする 2005/12/21

2-3:片方が削除されたクローン候補の抽出 Vt-1 において、対応がないクローンについて、 Vt との対応行とテキスト比較 クローン 関係 行番号 行番号 クローン 関係 ファイル1 ファイル1 Clone A Clone A クローン 履歴関係 Clone A ファイル2 ファイル2 Clone A Clone A Vt-1 において、対応がないクローンについて、 Vt との対応行とテキスト比較 ファイル3 Clone B ファイル3 Clone B Clone B HTt Vt-1 Vt 2005/12/21

提案手法の特徴 となりのバージョン同士でのつながり バージョン間の diff に対してのみクローン分析を適用 任意の二点間の分析を行うのはコストが大きい バージョン間の diff に対してのみクローン分析を適用 Vt-1, Vt 全体に対して CCFinder を適用するのはコストが大きい 各バージョンごとにクローン分析を適用 差分情報のみからクローン情報の類推を行わない 計算量を極力抑える 正確なクローン分析 2005/12/21

PostgreSQL のクローン履歴分析 分離クローンセットを漏れなく抽出できているかどうかの検証 クローン全体の履歴 PostgreSQL の src 部分を 2005/01/01 ~ 2005/06/30 の期間、一週間ごとに解析 クローンセット中のクローン数が減少している部分、時間に着目 その時間の差分を確認して、分離クローンセットか、縮退クローンセットかを目視で判定 分離クローンセットであれば、各クローンに正しくクローン履歴関係が抽出されているかどうかを検証 クローン全体の履歴 PostgreSQL の開発工程におけるクローンの増加量をグラフ化 1998年7月から2005年7月の6年分を一月区切りで解析 2005/12/21

縮退クローンセット 調査結果 全 24 クローンセットを調査 誤判定はなし 分岐クローンセット 4 本来は分岐クローンセットなのに、クローン減少と判定 クローンが削除されたクローンセット 5 価値のないクローンセット 15 全 24 クローンセットを調査 誤判定はなし 15箇所のクローンセットは、定数定義が連続している部分など無意味なクローン 2005/12/21

過去に関連のあったクローンセットの例 pgsql/src/backend/commands (SQL 文解釈・実行部の実装) pgsql/src/backend/commands/dbcommands.c 08/04 765 /* 766 * ALTER DATABASE name OWNER TO newowner 767 */ 768 void 769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) 770 { 771 HeapTuple tuple; 772 Relation rel; ・・・ 792 /* 793 * If the new owner is the same as the existing owner, consider the 794 * command to have succeeded. This is to be consistent with other objects. 795 */ 796 if (datForm->datdba != newOwnerSysId) 797 { 798 Datum repl_val[Natts_pg_database]; 799 char repl_null[Natts_pg_database]; 800 char repl_repl[Natts_pg_database]; 801 Acl *newAcl; 802 Datum aclDatum; 803 bool isNull; 804 HeapTuple newtuple; 805 806 /* changing owner's database for someone else: must be superuser */ 807 /* note that the someone else need not have any permissions */ 808 if (!superuser()) 809 ereport(ERROR, 810 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 811 errmsg("must be superuser to change owner"))); 812 813 memset(repl_null, ' ', sizeof(repl_null)); 814 memset(repl_repl, ' ', sizeof(repl_repl)); 815 816 repl_repl[Anum_pg_database_datdba - 1] = 'r'; 817 repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSysId); 818 819 /* 820 * Determine the modified ACL for the new owner. This is only 821 * necessary when the ACL is non-null. 822 */ 823 aclDatum = heap_getattr(tuple, 824 Anum_pg_database_datacl, 825 RelationGetDescr(rel), pgsql/src/backend/commands/dbcommands.c 07/01 765 /* 766 * ALTER DATABASE name OWNER TO newowner 767 */ 768 void 769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) 770 { 771 HeapTuple tuple, 772 newtuple; ・・・ 790 791 newtuple = heap_copytuple(tuple); 792 datForm = (Form_pg_database) GETSTRUCT(newtuple); 793 794 /* 795 * If the new owner is the same as the existing owner, consider the 796 * command to have succeeded. This is to be consistent with other objects. 797 */ 798 if (datForm->datdba != newOwnerSysId) 799 { 800 /* changing owner's database for someone else: must be superuser */ 801 /* note that the someone else need not have any permissions */ 802 if (!superuser()) 803 ereport(ERROR, 804 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 805 errmsg("must be superuser to change owner"))); 806 807 /* change owner */ 808 datForm->datdba = newOwnerSysId; 809 simple_heap_update(rel, &newtuple->t_self, newtuple); 810 CatalogUpdateIndexes(rel, newtuple); 811 } 812 813 systable_endscan(scan); 814 heap_close(rel, NoLock); 815 } pgsql/src/backend/commands (SQL 文解釈・実行部の実装) pgsql/src/backend/commands/aggregatecmds.c 07/01 291 /* 292 * Change aggregate owner 293 */ 294 void 295 AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) 296 { 297 Oid basetypeOid; 298 Oid procOid; ・・・ 321 if (!HeapTupleIsValid(tup)) /* should not happen */ 322 elog(ERROR, "cache lookup failed for function %u", procOid); 323 procForm = (Form_pg_proc) GETSTRUCT(tup); 324 325 /* 326 * If the new owner is the same as the existing owner, consider the 327 * command to have succeeded. This is for dump restoration purposes. 328 */ 329 if (procForm->proowner != newOwnerSysId) 330 { 331 /* Otherwise, must be superuser to change object ownership */ 332 if (!superuser()) 333 ereport(ERROR, 334 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 335 errmsg("must be superuser to change owner"))); 336 337 /* Modify the owner --- okay to scribble on tup because it's a copy */ 338 procForm->proowner = newOwnerSysId; 339 340 simple_heap_update(rel, &tup->t_self, tup); 341 CatalogUpdateIndexes(rel, tup); 342 } 343 344 heap_close(rel, NoLock); 345 heap_freetuple(tup); 346 } aggregatecmds.c Clone A conversioncmds.c conversioncmds.c aggregatecmds.c Clone A Clone A Clone A opclasscmds.c Clone A opclasscmds.c operatorcmds.c opratorcmds.c Clone A Clone A Clone A tablecmds.c Clone B functioncmds.c functioncmds.c tablespace.c Clone A Clone A tablespace.c Clone B Clone B schemacmds.c schemacmds.c dbcommands.c Clone A dbcommands.c Clone B Clone A Clone B 2005/03/04 2005/04/01 2005/12/21

考察 分離クローンセットを漏れなく抽出できているかどうかの検証 クローン量の変遷グラフ 縮退クローンセットに的を絞って検証 過去に関係のあったクローンの例 実際に関連性が高い 手動で履歴を探索していくのは手間がかかる 分析を行うための対話的ユーザインタフェースの作成 クローン量の変遷グラフ PostgreSQL の開発工程ではクローン含有率は安定 → 良好な開発パターン ただし src/backend/command 以下では上昇傾向 → 危険な傾向 危険なパターン、良好なパターンの列挙 2005/12/21

関連研究 クローンの生存期間に着目した分析* (Kim ら) クローン履歴を利用したオリジン分析** (Godfrey ら) ある一定間隔ごとにクローン分析を行い、クローンの寿命を調査 クローンの生存期間によってクローンを分類 クローン分析にはCCFinderを用いる クローン履歴を利用したオリジン分析** (Godfrey ら) 関数が、過去のバージョンのどの関数に由来するものかを調べる 関数の統合、分割を半自動的に検出 クローン分析はメトリクスベース 対話的な分析 利用するメトリクスは分析者が決定 * M. Kim and D. Notkin: “Using a clone genealogy extractor for understanding and supporting evolution of code clones”, MSR 2005, Saint Louis, Missouri, pp. 17-21 (2005) ** M. W. Godfrey and L. Zou: “Using origin analysis to detect merging and splitting of source code entities”, IEEE Trans. Software Engineering, 31, 2, pp.166-181 (2005) 2005/12/21

むすび ソフトウェアリポジトリに存在する大量のソフトウェアから、類似性を抽出しソフトウェア開発への応用を行った ソフトウェア自動分類システム MUDABlue の構築 事前知識なしでカテゴリを自動的に抽出し、分類 SourceForge から得たソフトウェアの分類実験 クローン履歴抽出手法の提案 コードクローンの履歴を抽出する手法の提案 PostgreSQL からの履歴抽出 2005/12/21

2005/12/21

特異値分解 特異値分解は、行列の次元を削減する 高次元配列の次元削減を行うメリット b 誤差は最小二乗誤差になるようにする。 l データサイズ削減 同じ値の分布をする次元(相関の高い次元)から優先的に一つの次元に併合される b l a 2 次元データ (a, b) を 1 次元 データ (l) に削減する例 2005/12/21

行番号の調整 ft ft-1 ft ft-1 衝突時には対応行が一意でない 最小、最大の推定値両方を考慮 9 18 24 29 34 39 挿入 9 Clone A 15 15 18 18 18 削除 22 Clone A 24 22 31 29 31 衝突 34 Clone A 36 Clone A ft-1 行番号 衝突時には対応行が一意でない 最小、最大の推定値両方を考慮 2005/12/21

分析2: PostgreSQL 全体のコード量 だしてる値はパーセントじゃない・・・(パーセントのほうが直感的かも) クローン含有率は開発工程全体をとおして安定 src 以下が全体の8割を占めている 2005/12/21

分析2: PostgreSQL コア部分のコード量 2000年11月、utils 以下のクローン含有率 utils には文字コード変換用データの大量追加 commands 以下のクローン率は徐々に上昇 2005/12/21

2005/12/21

今後の研究方針 クローン以外のエンティティに対する、過去情報を考慮した類似度測定 開発進捗度を考慮したソフトウェア類似判定 過去の開発過程を考慮したコンポーネント分類 2005/12/21

ソースコードや ドキュメントなどの 管理を行う 開発中に発見した バグの管理を行う 版管理システム バグ追跡システム ソフトウェアリポジトリ 掲示板 ML管理システム ユーザの要望等を 受け付ける 開発者間で行われた 議論を保存 2005/12/21

クローン履歴の活用法 2.コード中に含まれるコード クローンの変化を分析 1.過去に同じクローンセットだった クローンセットの発見 Clone A-3 追加 Clone A-3 Clone A-3 Clone A-1 Clone A-1 Clone A-1 Clone B-1 Clone B-1 Clone B-1 Clone A-4 Clone A-4, A-5 追加 Clone A-2 Clone A-2 Clone A-2 Clone B’-2 Clone B-5 Clone B’-2 Clone A-5 Clone B-2 Clone B-2 Clone B-2 Clone B’-1 Clone B-3 Clone B-4 Clone B’-3 Clone B’-1 Clone B’-3 Clone B-3, B-4, B-5 が編集 されて別クローンセットに Clone B’-3 削除 1.過去に同じクローンセットだった クローンセットの発見 2005/12/21

クローン履歴 2. ひとつのクローンセットを クローン発生時期から分類 1.過去に同じクローンセットだった クローンセットの発見 Clone A-3 追加 Clone A-3 Clone A-3 Clone A-1 Clone A-1 Clone A-1 Clone B-1 Clone B-1 Clone B-1 Clone A-4 Clone A-4, A-5 追加 Clone A-2 Clone A-2 Clone A-2 Clone B’-2 Clone B-5 Clone B’-2 Clone A-5 Clone B-2 Clone B-2 Clone B-2 Clone B’-1 Clone B-3 Clone B-4 Clone B’-3 Clone B’-1 Clone B’-3 Clone B-3, B-4, B-5 が編集 されて別クローンセットに Clone B’-3 削除 1.過去に同じクローンセットだった クローンセットの発見 3.コード中に含まれるコード クローンの変化を分析 2005/12/21

1: クローン分析 Vt 全体を CCFinder で分析 クローン 関係 クローン 履歴関係 Vt-1 Vt Clone A ファイル1 ファイル1 Clone A Clone A クローン 履歴関係 Clone A Vt 全体を CCFinder で分析 ファイル2 ファイル2 Clone A Clone A ファイル3 Clone B ファイル3 Clone B Clone B Vt-1 Vt 2005/12/21

Step1: クローン分析 Vt 全体を CCFinder で分析 クローン 関係 クローン 履歴関係 Vt-1 Vt Clone A ファイル1 ファイル1 Clone A Clone A クローン 履歴関係 Clone A Vt 全体を CCFinder で分析 ファイル2 ファイル2 Clone A Clone A Clone B ファイル3 Clone B ファイル3 Clone B Clone B Vt-1 Vt 2005/12/21

Step2-1: 編集されていないクローンの 履歴関係抽出 行番号 行番号 クローン 関係 ファイル1 ファイル1 7 Clone A 25 18 Clone A 31 37 クローン 履歴関係 43 Clone A ファイル2 ファイル2 22 22 Clone A 28 28 Clone A 編集操作による行番号のズレを吸収 Clone B ファイル3 11 Clone B ファイル3 22 42 30 Clone B 48 36 Clone B Vt の各クローンについて、Vt-1 の対応する 行にクローンが存在するかどうか検索 Vt-1 Vt 2005/12/21

行番号の調整 ft ft-1 ft ft-1 衝突時には対応行が一意でない 最小、最大の推定値両方を考慮 9 18 24 29 34 39 挿入 9 Clone A 15 15 18 18 18 削除 22 Clone A 24 22 31 29 31 衝突 34 Clone A 36 Clone A ft-1 行番号 衝突時には対応行が一意でない 最小、最大の推定値両方を考慮 2005/12/21

Step2-2: 追加されたクローンの 履歴関係抽出 ファイル1 ファイル1 Clone A Clone A クローン 履歴関係 Clone A ファイル2 ファイル2 Clone A Clone A Clone B ファイル3 Clone B ファイル3 Clone B Clone B Vt-1 と 差分との間で CCFinder を適用 Vt-1 Vt 発見したクローンに対応する部分を履歴関係とする 2005/12/21

まとめと今後の課題 自動ソフトウェア分類システム MUDABlue の提案 事前知識なしでカテゴリを自動的に発見し、ソフトウェアをカテゴライズすることを示した 今後の課題 「その他」カテゴリを減らす 識別子を選別する部分の改善が必要 カテゴリタイトルをよりわかりやすく 分かりやすいものもあれば、分かりにくいものも ライブラリに基づくカテゴリには分かりやすいタイトルがつく傾向 カテゴリの粒度 生成カテゴリの粒度は細粒度にすぎる傾向 2005/12/21

まとめ コードクローンの履歴を抽出する手法の提案 PostgreSQL から抽出した履歴の例の提示 課題 となりのバージョンだけで分析できないクローン履歴の抽出 一度削除されてまた後で復活したクローン 活用方法の考察 分析用ユーザインタフェースの作成 2005/12/21

過去に関連のあったクローンセットの例 pgsql/src/backend/commands (SQL 文解釈・実行部の実装) pgsql/src/backend/commands/dbcommands.c 08/04 765 /* 766 * ALTER DATABASE name OWNER TO newowner 767 */ 768 void 769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) 770 { 771 HeapTuple tuple; 772 Relation rel; ・・・ 792 /* 793 * If the new owner is the same as the existing owner, consider the 794 * command to have succeeded. This is to be consistent with other objects. 795 */ 796 if (datForm->datdba != newOwnerSysId) 797 { 798 Datum repl_val[Natts_pg_database]; 799 char repl_null[Natts_pg_database]; 800 char repl_repl[Natts_pg_database]; 801 Acl *newAcl; 802 Datum aclDatum; 803 bool isNull; 804 HeapTuple newtuple; 805 806 /* changing owner's database for someone else: must be superuser */ 807 /* note that the someone else need not have any permissions */ 808 if (!superuser()) 809 ereport(ERROR, 810 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 811 errmsg("must be superuser to change owner"))); 812 813 memset(repl_null, ' ', sizeof(repl_null)); 814 memset(repl_repl, ' ', sizeof(repl_repl)); 815 816 repl_repl[Anum_pg_database_datdba - 1] = 'r'; 817 repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSysId); 818 819 /* 820 * Determine the modified ACL for the new owner. This is only 821 * necessary when the ACL is non-null. 822 */ 823 aclDatum = heap_getattr(tuple, 824 Anum_pg_database_datacl, 825 RelationGetDescr(rel), pgsql/src/backend/commands/dbcommands.c 07/01 765 /* 766 * ALTER DATABASE name OWNER TO newowner 767 */ 768 void 769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) 770 { 771 HeapTuple tuple, 772 newtuple; ・・・ 790 791 newtuple = heap_copytuple(tuple); 792 datForm = (Form_pg_database) GETSTRUCT(newtuple); 793 794 /* 795 * If the new owner is the same as the existing owner, consider the 796 * command to have succeeded. This is to be consistent with other objects. 797 */ 798 if (datForm->datdba != newOwnerSysId) 799 { 800 /* changing owner's database for someone else: must be superuser */ 801 /* note that the someone else need not have any permissions */ 802 if (!superuser()) 803 ereport(ERROR, 804 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 805 errmsg("must be superuser to change owner"))); 806 807 /* change owner */ 808 datForm->datdba = newOwnerSysId; 809 simple_heap_update(rel, &newtuple->t_self, newtuple); 810 CatalogUpdateIndexes(rel, newtuple); 811 } 812 813 systable_endscan(scan); 814 heap_close(rel, NoLock); 815 } pgsql/src/backend/commands (SQL 文解釈・実行部の実装) pgsql/src/backend/commands/aggregatecmds.c 07/01 291 /* 292 * Change aggregate owner 293 */ 294 void 295 AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) 296 { 297 Oid basetypeOid; 298 Oid procOid; ・・・ 321 if (!HeapTupleIsValid(tup)) /* should not happen */ 322 elog(ERROR, "cache lookup failed for function %u", procOid); 323 procForm = (Form_pg_proc) GETSTRUCT(tup); 324 325 /* 326 * If the new owner is the same as the existing owner, consider the 327 * command to have succeeded. This is for dump restoration purposes. 328 */ 329 if (procForm->proowner != newOwnerSysId) 330 { 331 /* Otherwise, must be superuser to change object ownership */ 332 if (!superuser()) 333 ereport(ERROR, 334 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 335 errmsg("must be superuser to change owner"))); 336 337 /* Modify the owner --- okay to scribble on tup because it's a copy */ 338 procForm->proowner = newOwnerSysId; 339 340 simple_heap_update(rel, &tup->t_self, tup); 341 CatalogUpdateIndexes(rel, tup); 342 } 343 344 heap_close(rel, NoLock); 345 heap_freetuple(tup); 346 } aggregatecmds.c Clone A conversioncmds.c conversioncmds.c aggregatecmds.c Clone A Clone A Clone A opclasscmds.c Clone A opclasscmds.c operatorcmds.c opratorcmds.c Clone A Clone A Clone A tablecmds.c Clone B functioncmds.c functioncmds.c tablespace.c Clone A Clone A tablespace.c Clone B Clone B schemacmds.c schemacmds.c dbcommands.c Clone A dbcommands.c Clone B Clone A Clone B 2004/07/01 2004/08/04 2005/12/21