| 802 | } |
| 803 | |
| 804 | func (s *MultiIndexedArrayInMemoryStore) addAtom(a ast.Atom) bool { |
| 805 | if a.Predicate.Arity == 0 { |
| 806 | _, ok := s.constants[a.Predicate] |
| 807 | if !ok { |
| 808 | s.constants[a.Predicate] = a |
| 809 | return true |
| 810 | } |
| 811 | return false |
| 812 | } |
| 813 | aHash := a.Hash() |
| 814 | shard, ok := s.shardsByPredicate[a.Predicate] |
| 815 | if !ok { |
| 816 | shard = make(map[uint16]map[uint64]map[uint64][]*ast.Atom) |
| 817 | s.shardsByPredicate[a.Predicate] = shard |
| 818 | for i := 0; i < a.Predicate.Arity; i++ { |
| 819 | shard[uint16(i)] = make(map[uint64]map[uint64][]*ast.Atom) |
| 820 | iHash := a.Args[i].Hash() |
| 821 | shard[uint16(i)][iHash] = make(map[uint64][]*ast.Atom) |
| 822 | shard[uint16(i)][iHash][aHash] = append(shard[uint16(i)][iHash][aHash], &a) |
| 823 | } |
| 824 | return true |
| 825 | } |
| 826 | added := false |
| 827 | nextArg: |
| 828 | for i := 0; i < a.Predicate.Arity; i++ { |
| 829 | iHash := a.Args[i].Hash() |
| 830 | params, ok := shard[uint16(i)] |
| 831 | if !ok { |
| 832 | shard[uint16(i)] = make(map[uint64]map[uint64][]*ast.Atom) |
| 833 | shard[uint16(i)][iHash] = make(map[uint64][]*ast.Atom) |
| 834 | shard[uint16(i)][iHash][aHash] = append(shard[uint16(i)][iHash][aHash], &a) |
| 835 | added = true |
| 836 | continue |
| 837 | } |
| 838 | atoms, ok := params[iHash] |
| 839 | if !ok { |
| 840 | params[iHash] = make(map[uint64][]*ast.Atom) |
| 841 | params[iHash][aHash] = append(params[iHash][aHash], &a) |
| 842 | added = true |
| 843 | } else { |
| 844 | aList, ok := atoms[aHash] |
| 845 | if !ok { |
| 846 | atoms[aHash] = []*ast.Atom{&a} |
| 847 | added = true |
| 848 | continue |
| 849 | } |
| 850 | for _, atom := range aList { |
| 851 | if a.Equals(*atom) { |
| 852 | continue nextArg |
| 853 | } |
| 854 | } |
| 855 | atoms[aHash] = append(atoms[aHash], &a) |
| 856 | added = true |
| 857 | } |
| 858 | } |
| 859 | return added |
| 860 | } |
| 861 | |