ในระบบควบคุมเวอร์ชันแบบกระจาย (เช่นMercurialและGit ) มีความจำเป็นที่จะต้องเปรียบเทียบกราฟ acyclic (DAG) ที่มีประสิทธิภาพโดยตรง ฉันเป็นนักพัฒนา Mercurial และเราสนใจฟังเรื่องทฤษฎีที่พูดถึงเรื่องเวลาและความซับซ้อนของเครือข่ายในการเปรียบเทียบ DAG สองตัว
DAG ที่เป็นปัญหาจะเกิดขึ้นจากการแก้ไขที่บันทึกไว้ การแก้ไขจะถูกระบุโดยค่าแฮช แต่ละการแก้ไขขึ้นอยู่กับศูนย์ (การกระทำเริ่มต้น), หนึ่ง (การกระทำปกติ) หรือมากกว่า (รวมการกระทำ) ของการแก้ไขก่อนหน้านี้ นี่คือตัวอย่างที่การแก้ไขa
จะe
ทำทีละอย่าง:
a --- b --- c --- d --- e
การเปรียบเทียบกราฟเข้ามาในรูปภาพเมื่อมีบางส่วนของประวัติและต้องการเรียกคืนส่วนที่ขาด ลองนึกภาพผมมีa
ที่จะc
ทำx
และy
ขึ้นอยู่กับc
:
a --- b --- c --- x --- y
ใน Mercurial ฉันจะทำhg pull
และดาวน์โหลดd
และe
:
a --- b --- c --- x --- y
\
d --- e
เป้าหมายคือการระบุd
และe
มีประสิทธิภาพเมื่อกราฟมีโหนดจำนวนมาก (พูดมากกว่า 100,000 โหนด) ประสิทธิภาพเกี่ยวข้องกับทั้งสองอย่าง
- ความซับซ้อนของเครือข่าย:จำนวนไบต์ที่ถ่ายโอนและจำนวนเครือข่ายไปกลับที่จำเป็น
- ความซับซ้อนของเวลา:จำนวนการคำนวณที่กระทำโดยเซิร์ฟเวอร์สองเครื่องที่แลกเปลี่ยนเซ็ตการแก้ไข
กราฟทั่วไปจะแคบลงพร้อมกับแทร็กขนานสองสามรายการดังกล่าว โดยทั่วไปจะมีเพียงโหนดโหนดหนึ่งกำมือเท่านั้น (เราเรียกว่าหัวเป็น Mercurial) เหมือนe
และy
เหนือ ท้ายที่สุดเมื่อมีการใช้เซิร์ฟเวอร์กลางลูกค้ามักจะมีชุดการเปลี่ยนแปลงสองชุดที่ไม่ได้อยู่บนเซิร์ฟเวอร์ในขณะที่เซิร์ฟเวอร์สามารถมีชุดการเปลี่ยนแปลงใหม่กว่า 100+ ชุดขึ้นอยู่กับผู้ใช้ที่ดึงลูกค้าจากเซิร์ฟเวอร์มานานแล้ว . วิธีการแก้ปัญหาที่ไม่สมมาตรเป็นที่ต้องการ: เซิร์ฟเวอร์ส่วนกลางควรทำคำนวณเล็ก ๆ น้อย ๆ ในการเปรียบเทียบกับลูกค้าของตน