add delta tree (#4692)
introduces the delta tree in drive collections --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Issue(s) * #4689 #### Test Plan - [x] ⚡ Unit test
This commit is contained in:
parent
6fe6c9586d
commit
dbdd3f236c
80
src/internal/m365/collection/drive/delta_tree.go
Normal file
80
src/internal/m365/collection/drive/delta_tree.go
Normal file
@ -0,0 +1,80 @@
|
||||
package drive
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
)
|
||||
|
||||
// folderyMcFolderFace owns our delta processing tree.
|
||||
type folderyMcFolderFace struct {
|
||||
// tenant/service/resource/category/driveID
|
||||
// (or whatever variant the service defines)
|
||||
// allows the tree to focus only on folder structure,
|
||||
// and minimizes the possibility of multi-prefix path bugs.
|
||||
prefix path.Path
|
||||
|
||||
// the root of the tree;
|
||||
// new, moved, and notMoved collections
|
||||
collections *nodeyMcNodeFace
|
||||
|
||||
// the majority of operations we perform can be handled with
|
||||
// a folder ID lookup instead of re-walking the entire tree.
|
||||
// Ex: adding a new file to its parent folder.
|
||||
folderIDToNode map[string]*nodeyMcNodeFace
|
||||
|
||||
// tombstones don't need to form a tree.
|
||||
// we only need the folder ID and their previous path.
|
||||
tombstones map[string]path.Path
|
||||
|
||||
// it's just a sensible place to store the data, since we're
|
||||
// already pushing file additions through the api.
|
||||
excludeFileIDs map[string]struct{}
|
||||
}
|
||||
|
||||
func newFolderyMcFolderFace(
|
||||
prefix path.Path,
|
||||
) *folderyMcFolderFace {
|
||||
return &folderyMcFolderFace{
|
||||
prefix: prefix,
|
||||
folderIDToNode: map[string]*nodeyMcNodeFace{},
|
||||
tombstones: map[string]path.Path{},
|
||||
excludeFileIDs: map[string]struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
type nodeyMcNodeFace struct {
|
||||
// required for mid-enumeration folder moves, else we have to walk
|
||||
// the tree completely to remove the node from its old parent.
|
||||
parent *nodeyMcNodeFace
|
||||
// the microsoft item ID. Mostly because we might as well
|
||||
// attach that to the node if we're also attaching the dir.
|
||||
id string
|
||||
// single directory name, not a path
|
||||
name string
|
||||
// only contains the folders starting at and including '/root:'
|
||||
prev path.Path
|
||||
// map folderID -> node
|
||||
childDirs map[string]*nodeyMcNodeFace
|
||||
// items are keyed by item ID
|
||||
items map[string]time.Time
|
||||
// for special handling protocols around packages
|
||||
isPackage bool
|
||||
}
|
||||
|
||||
func newNodeyMcNodeFace(
|
||||
parent *nodeyMcNodeFace,
|
||||
id, name string,
|
||||
prev path.Path,
|
||||
isPackage bool,
|
||||
) *nodeyMcNodeFace {
|
||||
return &nodeyMcNodeFace{
|
||||
parent: parent,
|
||||
id: id,
|
||||
name: name,
|
||||
prev: prev,
|
||||
childDirs: map[string]*nodeyMcNodeFace{},
|
||||
items: map[string]time.Time{},
|
||||
isPackage: isPackage,
|
||||
}
|
||||
}
|
||||
56
src/internal/m365/collection/drive/delta_tree_test.go
Normal file
56
src/internal/m365/collection/drive/delta_tree_test.go
Normal file
@ -0,0 +1,56 @@
|
||||
package drive
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/tester"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
)
|
||||
|
||||
type DeltaTreeUnitSuite struct {
|
||||
tester.Suite
|
||||
}
|
||||
|
||||
func TestDeltaTreeUnitSuite(t *testing.T) {
|
||||
suite.Run(t, &DeltaTreeUnitSuite{Suite: tester.NewUnitSuite(t)})
|
||||
}
|
||||
|
||||
func (suite *DeltaTreeUnitSuite) TestNewFolderyMcFolderFace() {
|
||||
var (
|
||||
t = suite.T()
|
||||
p, err = path.BuildPrefix("t", "r", path.OneDriveService, path.FilesCategory)
|
||||
)
|
||||
|
||||
require.NoError(t, err, clues.ToCore(err))
|
||||
|
||||
folderFace := newFolderyMcFolderFace(p)
|
||||
assert.Equal(t, p, folderFace.prefix)
|
||||
assert.Nil(t, folderFace.collections)
|
||||
assert.NotNil(t, folderFace.folderIDToNode)
|
||||
assert.NotNil(t, folderFace.tombstones)
|
||||
assert.NotNil(t, folderFace.excludeFileIDs)
|
||||
}
|
||||
|
||||
func (suite *DeltaTreeUnitSuite) TestNewNodeyMcNodeFace() {
|
||||
var (
|
||||
t = suite.T()
|
||||
parent = &nodeyMcNodeFace{}
|
||||
p, err = path.Build("t", "r", path.SharePointService, path.LibrariesCategory, false, "drive-id", "root:")
|
||||
)
|
||||
|
||||
require.NoError(t, err, clues.ToCore(err))
|
||||
|
||||
nodeFace := newNodeyMcNodeFace(parent, "id", "name", p, true)
|
||||
assert.Equal(t, parent, nodeFace.parent)
|
||||
assert.Equal(t, "id", nodeFace.id)
|
||||
assert.Equal(t, "name", nodeFace.name)
|
||||
assert.Equal(t, p, nodeFace.prev)
|
||||
assert.True(t, nodeFace.isPackage)
|
||||
assert.NotNil(t, nodeFace.childDirs)
|
||||
assert.NotNil(t, nodeFace.items)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user