REVS_DIFF: Given a document ID and a set of revision IDs, looks up which ones are not known. Returns an array of the unknown revisions, and an array of known revisions that might be recent ancestors.
(ctx context.Context, docid string, revids []string)
| 3603 | // Given a document ID and a set of revision IDs, looks up which ones are not known. Returns an |
| 3604 | // array of the unknown revisions, and an array of known revisions that might be recent ancestors. |
| 3605 | func (db *DatabaseCollectionWithUser) RevDiff(ctx context.Context, docid string, revids []string) (missing, possible []string) { |
| 3606 | if strings.HasPrefix(docid, "_design/") && db.user != nil { |
| 3607 | return // Users can't upload design docs, so ignore them |
| 3608 | } |
| 3609 | |
| 3610 | syncData, _, err := db.GetDocSyncDataNoImport(ctx, docid, DocUnmarshalHistory) |
| 3611 | if err != nil { |
| 3612 | if !base.IsDocNotFoundError(err) && !base.IsXattrNotFoundError(err) { |
| 3613 | base.WarnfCtx(ctx, "RevDiff(%q) --> %T %v", base.UD(docid), err, err) |
| 3614 | } |
| 3615 | missing = revids |
| 3616 | return |
| 3617 | } |
| 3618 | // Check each revid to see if it's in the doc's rev tree: |
| 3619 | revidsSet := base.SetFromArray(revids) |
| 3620 | possibleSet := make(map[string]bool) |
| 3621 | for _, revid := range revids { |
| 3622 | if !syncData.History.contains(revid) { |
| 3623 | missing = append(missing, revid) |
| 3624 | // Look at the doc's leaves for a known possible ancestor: |
| 3625 | if gen, _ := ParseRevID(ctx, revid); gen > 1 { |
| 3626 | syncData.History.forEachLeaf(func(possible *RevInfo) { |
| 3627 | if !revidsSet.Contains(possible.ID) { |
| 3628 | possibleGen, _ := ParseRevID(ctx, possible.ID) |
| 3629 | if possibleGen < gen && possibleGen >= gen-100 { |
| 3630 | possibleSet[possible.ID] = true |
| 3631 | } else if possibleGen == gen && possible.Parent != "" { |
| 3632 | possibleSet[possible.Parent] = true // since parent is < gen |
| 3633 | } |
| 3634 | } |
| 3635 | }) |
| 3636 | } |
| 3637 | } |
| 3638 | } |
| 3639 | |
| 3640 | // Convert possibleSet to an array (possible) |
| 3641 | if len(possibleSet) > 0 { |
| 3642 | possible = make([]string, 0, len(possibleSet)) |
| 3643 | for revid, _ := range possibleSet { |
| 3644 | possible = append(possible, revid) |
| 3645 | } |
| 3646 | } |
| 3647 | return |
| 3648 | } |
| 3649 | |
| 3650 | // Status code returned by CheckProposedRev |
| 3651 | type ProposedRevStatus int |