| @@ -0,0 +1,99 @@ | ||
| package lca | ||
| type node struct { | ||
| name string | ||
| children []*node | ||
| ancestor *node | ||
| rank int | ||
| color int | ||
| parent *node | ||
| } | ||
| type Data struct { | ||
| Name string | ||
| Children []*Data | ||
| } | ||
| var root, target_node_1, target_node_2 *node | ||
| func makeset(n *node) { | ||
| n.parent = n | ||
| n.rank = 1 | ||
| } | ||
| func union(nodex, nodey *node) { | ||
| xroot := find(nodex) | ||
| yroot := find(nodey) | ||
| if xroot.rank > yroot.rank { | ||
| yroot.parent = xroot | ||
| } else if xroot.rank < yroot.rank { | ||
| xroot.parent = yroot | ||
| } else if xroot.rank == yroot.rank { | ||
| yroot.parent = xroot | ||
| xroot.rank += 1 | ||
| } | ||
| } | ||
| func find(node *node) *node { | ||
| if node.parent != node { | ||
| node.parent = find(node.parent) | ||
| } | ||
| return node.parent | ||
| } | ||
| func lca(node *node) (*node, bool) { | ||
| makeset(node) | ||
| node.ancestor = node | ||
| for _, child := range node.children { | ||
| return_value, found := lca(child) | ||
| if found == true { | ||
| return return_value, found | ||
| } | ||
| union(node, child) | ||
| this_node := find(node) | ||
| this_node.ancestor = node | ||
| } | ||
| node.color = 1 | ||
| if node.name == target_node_2.name && target_node_2.color == 1 && target_node_1.color == 1 { | ||
| return_val := find(target_node_1).ancestor | ||
| return return_val, true | ||
| } else if node.name == target_node_1.name && target_node_2.color == 1 && target_node_1.color == 1 { | ||
| return_val := find(target_node_2).ancestor | ||
| return return_val, true | ||
| } else { | ||
| return nil, false | ||
| } | ||
| } | ||
| func find_node_by_name(name string, parent *node) (*node, bool) { | ||
| if parent.name == name { | ||
| return parent, true | ||
| } | ||
| for _, child := range parent.children { | ||
| node, found := find_node_by_name(name, child) | ||
| if found == true { | ||
| return node, true | ||
| } | ||
| } | ||
| return nil, false | ||
| } | ||
| func build_tree(data *Data) *node { | ||
| node := &node{name: data.Name} | ||
| for _,child := range data.Children { | ||
| child_node := build_tree(child) | ||
| node.children = append(node.children, child_node) | ||
| } | ||
| return node | ||
| } | ||
| func Search(name1, name2 string) string { | ||
| target_node_1, _ = find_node_by_name(name1, root) | ||
| target_node_2, _ = find_node_by_name(name2, root) | ||
| ancestor, _ := lca(root) | ||
| return ancestor.name | ||
| } | ||
| func Init(data *Data) { | ||
| root = build_tree(data) | ||
| } |
| @@ -0,0 +1,39 @@ | ||
| package lca | ||
| import "testing" | ||
| func TestSearch(t *testing.T) { | ||
| var one, two, three, four, five, six, seven *Data | ||
| one = &Data{Name: "1"} | ||
| two = &Data{Name: "2"} | ||
| three = &Data{Name: "3"} | ||
| four = &Data{Name: "4"} | ||
| five = &Data{Name: "5"} | ||
| six = &Data{Name: "6"} | ||
| seven = &Data{Name: "7"} | ||
| one.Children = append(one.Children, two) | ||
| one.Children = append(one.Children, three) | ||
| two.Children = append(two.Children, four) | ||
| two.Children = append(two.Children, five) | ||
| three.Children = append(three.Children, six) | ||
| three.Children = append(three.Children, seven) | ||
| Init(one) | ||
| ancestor := Search("3", "4") | ||
| if ancestor != "1" { | ||
| t.Errorf("Search was incorrect, got: %s, want %s", ancestor, "1") | ||
| } | ||
| Init(one) | ||
| ancestor = Search("5", "4") | ||
| if ancestor != "2" { | ||
| t.Errorf("Search was incorrect, got: %s, want %s", ancestor, "2") | ||
| } | ||
| Init(one) | ||
| ancestor = Search("7", "1") | ||
| if ancestor != "1" { | ||
| t.Errorf("Search was incorrect, got: %s, want %s", ancestor, "1") | ||
| } | ||
| } |
| @@ -0,0 +1,82 @@ | ||
| package employee_model | ||
| import ( | ||
| "ccm/datastore/memory" //should have been an interface rather | ||
| "ccm/lib/lca" | ||
| "strconv" | ||
| ) | ||
| type Employee struct { | ||
| Id int | ||
| Name string | ||
| Manages []*Employee | ||
| } | ||
| func Create(name string) *Employee { | ||
| employee := &Employee{Name: name} | ||
| return employee | ||
| } | ||
| func (employee_obj *Employee) Save() *Employee { | ||
| var data map[string]interface{} | ||
| data = make(map[string]interface{}) | ||
| data["name"] = employee_obj.Name //Not checking if names are duplicates | ||
| manages_employee_id := []int{} | ||
| for _, employee := range employee_obj.Manages { | ||
| manages_employee_id = append(manages_employee_id, employee.Id) | ||
| } | ||
| data["manages_employee_id"] = manages_employee_id | ||
| if employee_obj.Id == 0 { | ||
| saved_data := memory.Set(data) | ||
| employee_obj.Id = saved_data.Id | ||
| } else { | ||
| memory.Update(employee_obj.Id, data) | ||
| } | ||
| return employee_obj | ||
| } | ||
| func (manager_obj *Employee) Link_employee(employee_obj *Employee) { | ||
| manager_obj.Manages = append(manager_obj.Manages, employee_obj) | ||
| manager_obj.Save() | ||
| } | ||
| func build_data(data *Employee) *lca.Data { | ||
| //this should be elsewhere | ||
| employee_node := &lca.Data{Name: data.Name} | ||
| for _, employee := range data.Manages { | ||
| employee_child_node := build_data(employee) | ||
| employee_node.Children = append(employee_node.Children, employee_child_node) | ||
| } | ||
| return employee_node | ||
| } | ||
| func Search_common_manager (ceo, employee1, employee2 *Employee) *Employee { | ||
| data := build_data(ceo) | ||
| lca.Init(data) | ||
| common_manager := lca.Search(employee1.Name, employee2.Name) | ||
| common_manager_obj := Find_by_name(common_manager) | ||
| return common_manager_obj | ||
| } | ||
| func Delete() {} | ||
| func Find() {} | ||
| func build_employee_obj(data *memory.Entry) *Employee { | ||
| employee_obj := &Employee{Id: data.Id, Name: data.Data["name"].(string)} | ||
| for _, id := range data.Data["manages_employee_id"].([]int) { | ||
| me_entry := memory.Get("Id", strconv.Itoa(id)) | ||
| me_obj := build_employee_obj(me_entry) | ||
| employee_obj.Manages = append(employee_obj.Manages, me_obj) | ||
| } | ||
| return employee_obj | ||
| } | ||
| func Find_by_name(name string) *Employee{ | ||
| employee := memory.Get("name", name) | ||
| employee_obj := build_employee_obj(employee) | ||
| return employee_obj | ||
| } |
| @@ -0,0 +1,39 @@ | ||
| package employee_model | ||
| import "testing" | ||
| func TestCreate(t *testing.T) { | ||
| employee := Create("Claire") | ||
| if employee.Name != "Claire" { | ||
| t.Errorf("Create was incorrect, got: %s, want %s", employee.Name, "Claire") | ||
| } | ||
| } | ||
| func TestSave(t *testing.T) { | ||
| employee := Create("Claire") | ||
| employee_obj := employee.Save() | ||
| if employee_obj.Id != 1 { | ||
| t.Errorf("Save failed. id got: %d, want: %d", employee_obj.Id, 1) | ||
| } | ||
| employee2 := Create("Claire 2") | ||
| employee_obj = employee2.Save() | ||
| if employee_obj.Id != 2 { | ||
| t.Errorf("Save failed. id got: %d, want: %d", employee_obj.Id, 2) | ||
| } | ||
| } | ||
| func TestLink_employee(t *testing.T) { | ||
| employee := Create("Claire") | ||
| employee_obj := employee.Save() | ||
| employee2 := Create("Claire 2") | ||
| employee2_obj := employee2.Save() | ||
| employee_obj.Link_employee(employee2_obj) | ||
| if len(employee_obj.Manages) != 1 { | ||
| t.Errorf("Link failed. lenght got: %d, want: %d", len(employee_obj.Manages), 1) | ||
| } | ||
| } |
| @@ -0,0 +1,3 @@ | ||
| package employee_repo | ||
| import "ccm/model/employee_model" |