Commit 5c42431

Richard Luby <richluby@gmail.com>
2016-12-21 12:46:58
categories created properly
categories are created heirarchically and properly stored in memory. tree supports multiple categorical roots if body of knowledge is arranged in such a manner
1 parent cabf6c4
question.go
@@ -12,25 +12,30 @@ import (
 // buildTagPath creates the heirarchical list of tags
 // given the linearly related tag relationship
 // returns the index of the newly created category
-func buildTagPath(tags []string, parent int, currentTag int) int {
-	if len(tags) <= currentTag {
-		return parent
-	}
-	if newParent := getNearestParentCategory(tags[currentTag : len(tags)-1]); newParent >= 0 {
-		numParents := 0
-		for checkForParent := categories[newParent]; checkForParent.Parent >= 0; checkForParent = categories[checkForParent.Parent] {
-			numParents++
+func buildTagPath(tags []string) int {
+	currentChosen := getNearestParentCategory(tags)
+	if currentChosen < 0 {//not found in tree
+		for _, tag := range tags{
+			cat := Category{Parent : len(categories)-1,
+			Value : tag}
+			categories = append(categories, cat)
+			currentChosen = len(categories)-1
+		}
+		categories[len(categories)-len(tags)].Parent = -1
+	} else { // some parent found somewhere
+		tagIndex := 0
+		for parentIndex := currentChosen; parentIndex >=0; parentIndex = categories[parentIndex].Parent{
+			tagIndex++ // counting the depth in the tree
+		}
+		for  tagIndex < len(tags){// everything from here on is unkown and needs creation
+			newCat := Category{Parent : currentChosen,
+			Value : tags[tagIndex]}
+			categories = append(categories, newCat)
+			currentChosen = len(categories) -1
+			tagIndex++
 		}
-		return buildTagPath(tags, newParent, currentTag+numParents) // should increment by numTagsFound
 	}
-	category := Category{}
-	category.Value = tags[currentTag]
-	category.Parent = parent
-	categories = append(categories, category)
-	category.Children = append(category.Children,
-		len(categories)-1)
-	//log.Printf("Node (%s) added for child of %s with tag %s: %+v", categories[parent].FullCategoryPath(), tags[currentTag], tags)
-	return buildTagPath(tags, len(categories)-1, currentTag+1)
+	return currentChosen
 }
 
 // assignCategory figures out what category
@@ -42,7 +47,7 @@ func assignCategory(file *os.File) int {
 	if tags[0] == "" {
 		tags = tags[1:]
 	}
-	return buildTagPath(tags, -1, 0)
+	return buildTagPath(tags)
 }
 
 // parseLine parses a csv line and returns a single record
@@ -90,7 +95,6 @@ func LoadFile(file *os.File) error {
 // loadRecords loads the records into memory according to
 // the supplied configuration for the given file.
 func loadRecords(path string, fileInfo os.FileInfo, err error) error {
-	log.Printf("cats: %+v", categories)
 	file, err := os.Open(path)
 	if err != nil {
 		return err
structures_test.go
@@ -28,18 +28,25 @@ func TestBuildTree(t *testing.T) {
 	categories = []Category{}
 	catPath := []string{"Cyber", "linux", "shell", "bash"}
 	for i, _ := range catPath {
-		catIndex := buildTagPath(catPath[0:i+1], -1, 0)
+		catIndex := buildTagPath(catPath[0 : i+1])
 		if catIndex != i {
 			t.Errorf("Catindex wrong: %d should be %d", catIndex, i)
 		}
 	}
-	if len(categories) != len(catPath) {
+	catPath = []string{"Winderp", "proc", "reg", "keys"}
+	for i, _ := range catPath {
+		catIndex := buildTagPath(catPath[0 : i+1])
+		if catIndex != i+len(catPath) {
+			t.Errorf("Catindex wrong: %d should be %d", catIndex, i+len(catPath))
+		}
+	}
+	if len(categories) != 2*len(catPath) {
 		t.Errorf("Categories wrong len: %d\t%+v", len(categories), categories)
 		t.FailNow()
 	}
-	for i, cat := range categories {
-		if i >= len(catPath) || cat.Value != catPath[i] {
-			t.Errorf("Improper category: %s for index %d", cat.Value, i)
+	for i := len(catPath); i < len(categories); i++ {
+		if i >= len(categories) || categories[i].Value != catPath[i-len(catPath)] {
+			t.Errorf("Improper category: %s for index %d\n%+v", categories[i].Value, i, categories)
 			t.FailNow()
 		}
 	}