| 
					
				 | 
			
			
				@@ -59,7 +59,7 @@ func TestBullshitFile(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	assert.Equal(t, alloc.Size(), 3)  // 1 + 2 nodes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func TestCloneFile(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func TestCloneFileShallow(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	file, status, alloc := fixtureFile() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 0 | 100 -1                             [0]: 100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	file.Update(1, 20, 30, 0) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -71,7 +71,7 @@ func TestCloneFile(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	file.Update(4, 20, 10, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 0 | 20 4 | 30 1 | 50 0 | 130 -1        [0]: 100, [1]: 20, [4]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	assert.Equal(t, alloc.Size(), 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	clone := file.Clone(alloc.Clone()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clone := file.CloneShallow(alloc.Clone()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	clone.Update(5, 45, 0, 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 0 | 20 4 | 30 1 | 45 0 | 120 -1        [0]: 95, [1]: 15, [4]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	clone.Update(6, 45, 5, 0) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -100,7 +100,49 @@ func TestCloneFile(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 50 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 125 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	assert.Equal(t, "0 0\n20 4\n30 1\n45 6\n50 0\n125 -1\n", dump) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func TestCloneFileDeep(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file, status, alloc := fixtureFile() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 100 -1                             [0]: 100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file.Update(1, 20, 30, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 1 | 50 0 | 130 -1               [0]: 100, [1]: 30 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file.Update(2, 20, 0, 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 1 | 45 0 | 125 -1               [0]: 100, [1]: 25 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file.Update(3, 20, 0, 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 1 | 40 0 | 120 -1               [0]: 100, [1]: 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file.Update(4, 20, 10, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 4 | 30 1 | 50 0 | 130 -1        [0]: 100, [1]: 20, [4]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, alloc.Size(), 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clone := file.CloneDeep(rbtree.NewAllocator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clone.Update(5, 45, 0, 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 4 | 30 1 | 45 0 | 120 -1        [0]: 95, [1]: 15, [4]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clone.Update(6, 45, 5, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 4 | 30 1 | 45 6 | 50 0 | 125 -1 [0]: 95, [1]: 15, [4]: 10, [6]: 5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(95), status[0]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(15), status[1]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(0), status[2]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(0), status[3]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(10), status[4]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(0), status[5]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(5), status[6]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dump := file.Dump() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Output: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 20 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 30 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 50 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 130 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, "0 0\n20 4\n30 1\n50 0\n130 -1\n", dump) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dump = clone.Dump() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Output: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 20 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 30 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 45 6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 50 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 125 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, "0 0\n20 4\n30 1\n45 6\n50 0\n125 -1\n", dump) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func TestLenFile(t *testing.T) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -401,7 +443,8 @@ func TestBug3File(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func TestBug4File(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	status := map[int]int64{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	file := NewFile(0, 10, rbtree.NewAllocator(), func(a, b, c int) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	alloc := rbtree.NewAllocator() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file := NewFile(0, 10, alloc, func(a, b, c int) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		updateStatusFile(status, a, b, c) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 0 | 10 -1 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -459,6 +502,8 @@ func TestBug4File(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 125 | 2 215 | 27 214 | 28 300 | 29 214 | 30 215 | 37 214 | 40 215 | 44 125 | 46 215 | 48 125 | 49 215 | 69 125 | 73 215 | 79 125 | 80 0 | 81 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	dump = file.Dump() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	assert.Equal(t, "0 125\n2 215\n27 214\n28 300\n29 214\n30 215\n37 214\n40 215\n44 125\n46 215\n48 125\n49 215\n69 125\n73 215\n79 125\n80 0\n81 -1\n", dump) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, 1 + file.tree.Len(), alloc.Used()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, file.Nodes(), file.tree.Len()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func TestBug5File(t *testing.T) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -574,7 +619,7 @@ func TestFileMergeMark(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	assert.NotContains(t, status, TreeMergeMark) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func TestFileMerge(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func TestFileMergeShallow(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	file1, status, alloc := fixtureFile() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 0 | 100 -1                             [0]: 100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	file1.Update(1, 20, 30, 0) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -585,7 +630,46 @@ func TestFileMerge(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 0 | 20 1 | 40 0 | 120 -1               [0]: 100, [1]: 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	file1.Update(4, 20, 10, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 0 | 20 4 | 30 1 | 50 0 | 130 -1        [0]: 100, [1]: 20, [4]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	file2 := file1.Clone(alloc.Clone()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file2 := file1.CloneShallow(alloc.Clone()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file1.Update(TreeMergeMark, 60, 30, 30) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 4 | 30 1 | 50 0 | 60 M | 90 0 | 130 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// [0]: 70, [1]: 20, [4]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file2.Update(5, 60, 20, 20) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 4 | 30 1 | 50 0 | 60 5 | 80 0 | 130 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// [0]: 80, [1]: 20, [4]: 10, [5]: 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file2.Update(TreeMergeMark, 80, 10, 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 4 | 30 1 | 50 0 | 60 5 | 80 M | 90 0 | 130 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// [0]: 70, [1]: 20, [4]: 10, [5]: 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file2.Update(6, 0, 10, 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 6 | 10 0 | 20 4 | 30 1 | 50 0 | 60 5 | 80 M | 90 0 | 130 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// [0]: 60, [1]: 20, [4]: 10, [5]: 20, [6]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file1.Merge(7, file2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 4 | 30 1 | 50 0 | 60 5 | 80 7 | 90 0 | 130 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// [0]: 70, [1]: 20, [4]: 10, [5]: 20, [6]: 0, [7]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dump := file1.Dump() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, "0 0\n20 4\n30 1\n50 0\n60 5\n80 7\n90 0\n130 -1\n", dump) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(70), status[0]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(20), status[1]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(0), status[2]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(0), status[3]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(10), status[4]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(20), status[5]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(10), status[6]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	assert.Equal(t, int64(10), status[7]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func TestFileMergeDeep(t *testing.T) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file1, status, _ := fixtureFile() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 100 -1                             [0]: 100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file1.Update(1, 20, 30, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 1 | 50 0 | 130 -1               [0]: 100, [1]: 30 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file1.Update(2, 20, 0, 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 1 | 45 0 | 125 -1               [0]: 100, [1]: 25 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file1.Update(3, 20, 0, 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 1 | 40 0 | 120 -1               [0]: 100, [1]: 20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file1.Update(4, 20, 10, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// 0 0 | 20 4 | 30 1 | 50 0 | 130 -1        [0]: 100, [1]: 20, [4]: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	file2 := file1.CloneDeep(rbtree.NewAllocator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	file1.Update(TreeMergeMark, 60, 30, 30) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 0 0 | 20 4 | 30 1 | 50 0 | 60 M | 90 0 | 130 -1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// [0]: 70, [1]: 20, [4]: 10 
			 |