Advertisement
Guest User

Untitled

a guest
Jan 21st, 2020
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.24 KB | None | 0 0
  1. module.exports.setWIndexKeys = async (secret) => {
  2. _key1 = generateKey(secret, secret);
  3. _key2 = generateKey(_key1, secret);
  4. _key3 = generateKey(_key2, secret);
  5. };
  6.  
  7. module.exports.setWIndexSettings = async (key, opts) => {
  8. const indexASchema = new mongoose.Schema({
  9. t: { type: Buffer }
  10. }, { strict: false });
  11. const indexTSchema = new mongoose.Schema({
  12. _index: mongoose.Mixed,
  13. s: Object,
  14. d: Object
  15. }, { strict: false });
  16. _indexAModel = mongoose.model("indexA", indexASchema);
  17. _indexTModel = mongoose.model("indexT", indexTSchema);
  18. const indexT = await _indexTModel.find({ _index: key }).exec().catch(err => {
  19. throw new PersonalDataStorageError(err);
  20. });
  21.  
  22. if (!indexT.length) {
  23. _word_index_id[key] = mongoose.Types.ObjectId();
  24. const instance = new _indexTModel({
  25. _id: _word_index_id[key],
  26. _index: key,
  27. Ts: {}
  28. });
  29.  
  30. await instance.save(opts).catch(err => {
  31. throw new PersonalDataStorageError(err);
  32. });
  33. } else {
  34. if (indexT.length !== 1) throw new PersonalDataStorageError(`Find more than 1 index for ${key}`);
  35. _word_index_id[key] = indexT[0]._id;
  36. }
  37. };
  38.  
  39. module.exports.AddAs = async (word, file_id, key, opts) => {
  40. const dataForXor = generateDataForXorAs(word);
  41. _opts = opts;
  42. let arrAsId = [];
  43. const Dn_id = mongoose.Types.ObjectId();
  44. //проверить существует ли это слово в Ts
  45. const Fk1_word = F(word, _key1);
  46.  
  47.  
  48. const record_in_Ts = `s.${Fk1_word}`;
  49. let [ Ts ] = await _indexTModel.aggregate([
  50. { $match: { _id: _word_index_id[key], [record_in_Ts]: { $exists: true } } },
  51. { $project: { [record_in_Ts]: 1 } }
  52. ]);
  53.  
  54. let As;
  55.  
  56. //если слово не существует то добавляю запсь в коллекцию indexAs
  57. if (!Ts){
  58. As = await createAsIndex({
  59. file: file_id,
  60. addrDn: Dn_id,
  61. next: 0
  62. }, dataForXor);
  63.  
  64.  
  65. //добавляю запись в Ts
  66. Ts = await _indexTModel.findOneAndUpdate({ _id: _word_index_id[key] }, {
  67. $set: { [record_in_Ts]: String(xor(String(As._id), G(word, _key2))) }
  68. } , opts).catch(err =>{
  69. throw new PersonalDataStorageError(err);
  70. });
  71.  
  72. arrAsId.push(As._id);
  73.  
  74. return { [word]: {
  75. Ad_id: Dn_id,
  76. arrAs: arrAsId,
  77. As_minus : 0
  78. } };
  79. }
  80. else {
  81.  
  82.  
  83. As = await findAsIndex({ _id: String(xor(Ts.s[Fk1_word], G(word, _key2))) }, dataForXor);
  84. arrAsId.push(As._id);
  85.  
  86.  
  87. //find latest record in As
  88. while (As.next !== 0){
  89. As = await findAsIndex({ _id: As.next }, dataForXor);
  90. arrAsId.push(As._id);
  91. }
  92.  
  93. const id = mongoose.Types.ObjectId();
  94. arrAsId.push(id);
  95.  
  96. await createAsIndex({
  97. _id: id,
  98. file: file_id,
  99. addrDn: Dn_id,
  100. next: 0
  101. }, dataForXor);
  102.  
  103. await findAndUpdateAsIndex({
  104. _id: As._id,
  105. next: id
  106. }, dataForXor);
  107.  
  108. return { [word]: {
  109. Ad_id: Dn_id,
  110. arrAs: arrAsId,
  111. As_minus: As.addrDn
  112. }};
  113. }
  114. };
  115.  
  116.  
  117.  
  118. //создание и обновление индексов для удаления
  119. module.exports.AddAd = async (fileId, objAsId, key, opts) => {
  120. const dataForXor = generateDataForXorAd(String(fileId));
  121. fileId = String(fileId);
  122. //создать Ad
  123. const arrayAdId = Object.keys(objAsId).map(key => objAsId[key].Ad_id);
  124. const As_minus_arr = Object.keys(objAsId).map(key => objAsId[key].As_minus);
  125. Object.keys(objAsId).map(key => {
  126. objAsId[key] = objAsId[key].arrAs
  127. });
  128.  
  129. await Promise.all(Object.keys(objAsId).map(async (word, index) => {
  130.  
  131. if (As_minus_arr[index]){
  132.  
  133.  
  134. return findAndUpdateAdIndex({
  135. _id: ObjectId(As_minus_arr[index]),
  136. }, undefined, Buffer.concat([
  137. new Buffer.alloc(56),
  138. xor(String(arrayAdId[index]), _null),
  139. new Buffer.alloc(57),
  140. xor(String(objAsId[word][objAsId[word].length - 1]), _null),
  141. new Buffer.alloc(93)
  142. ]))
  143. }
  144. }));
  145.  
  146. const res = await Object.keys(objAsId).map((word, index) => {
  147. const obj = {
  148. addrD_plus: Object.keys(objAsId).length - 1 > index ? String(arrayAdId[index + 1]) : _null,
  149. addrNd_minus: As_minus_arr[index] ? String(As_minus_arr[index]) : _null,
  150. addrNd_plus: _null,
  151. addrN: objAsId[word][objAsId[word].length - 1] ? String(objAsId[word][objAsId[word].length - 1]) : _null,
  152. addrN_minus: objAsId[word].length > 1 ? String(objAsId[word][objAsId[word].length - 2]) : _null,
  153. addrN_plus: _null,
  154. word: F(word, _key1)
  155. };
  156. return {
  157. _id: arrayAdId[index],
  158. t: xor(JSON.stringify([ obj.addrD_plus, obj.addrNd_minus, obj.addrNd_plus, obj.addrN, obj.addrN_minus, obj.addrN_plus, obj.word ]), dataForXor)
  159. }
  160. });
  161.  
  162. await _indexAModel.insertMany(res).catch(err => {
  163. throw new PersonalDataStorageError(err);
  164. });
  165.  
  166. //создать Td
  167. const Fk1_file = F(fileId, _key1);
  168. const record_in_Td = `d.${Fk1_file}`;
  169.  
  170.  
  171. Ts = await _indexTModel.findOneAndUpdate({ _id: _word_index_id[key] }, {
  172. $set: { [record_in_Td]: String(xor(String(arrayAdId[0]), G(fileId, _key2))) }
  173. } , opts).catch(err =>{
  174. throw new PersonalDataStorageError(err);
  175. });
  176. };
  177.  
  178. module.exports.Search = async (word, key, opts) => {
  179. //найти запись в Ts
  180. const dataForXor = generateDataForXorAs(word);
  181. const Fk1_word = F(word, _key1);
  182. const record_in_Ts = `s.${Fk1_word}`;
  183. let [ Ts ] = await _indexTModel.aggregate([
  184. { $match: { _id: _word_index_id[key], [record_in_Ts]: { $exists: true } } },
  185. { $project: { [record_in_Ts]: 1 } }
  186. ]);
  187.  
  188. if(!Ts) return null;
  189.  
  190. let arrId = []
  191. //если есть, то найти первый элемент в As
  192. let As = await findAsIndex({ _id: String(xor(Ts.s[Fk1_word], G(word, _key2))) }, dataForXor);
  193. arrId.push(As.file);
  194.  
  195. //найти все элементы пока (next !== 0)
  196. while(As.next !== 0){
  197. As = await findAsIndex({ _id: As.next }, dataForXor);
  198. arrId.push(As.file);
  199. }
  200.  
  201. return arrId;
  202. };
  203.  
  204. module.exports.Delete = async (fileId, key) => {
  205.  
  206. fileId = String(fileId);
  207. const dataForXor = generateDataForXorAd(fileId);
  208.  
  209. //вычислить хэш от id file
  210. const Fk1_file = F(fileId, _key1);
  211. const record_in_Td = `d.${Fk1_file}`;
  212.  
  213. const Td = await _indexTModel.findOneAndUpdate( //TODO вернуть только нужные значение!!!!
  214. { _id: _word_index_id[key] },
  215. { $unset: { [record_in_Td]: 1 }},
  216. { projection: { [record_in_Td]: 1 }}
  217. ).catch(err =>{
  218. throw new PersonalDataStorageError(err);
  219. });
  220.  
  221.  
  222. let Ad_addr = String(xor(String(Td.d[Fk1_file]), G(fileId, _key2)));
  223.  
  224.  
  225.  
  226. while (Ad_addr !== _null){
  227. let Ad = await findOneAndRemoveAdIndex({ _id: Ad_addr }, dataForXor);
  228.  
  229. //обновить Nd_plus и N+1 в индексе Ad по адресу Nd_minus на Nd_plus и N+1
  230. if (Ad.addrNd_minus !== _null){
  231. await findAndUpdateAdIndex({
  232. _id: Ad.addrNd_minus,
  233. addrNd_plus: Ad.addrNd_plus,
  234. addrN_plus: Ad.addrN_plus
  235. }, undefined, Buffer.concat([
  236. new Buffer.alloc(56),
  237. xor(Ad.addrNd_plus, String(Ad._id)),
  238. new Buffer.alloc(57),
  239. xor(Ad.addrN_plus, Ad.addrN),
  240. new Buffer.alloc(93)
  241. ]))
  242. }
  243.  
  244. //обновить Nd_minus и N-1 в индексе Ad по адресу Nd_plus на Nd_minus и N-1
  245. if (Ad.addrNd_plus !== _null){
  246. await findAndUpdateAdIndex({
  247. _id: Ad.addrNd_plus,
  248. addrNd_minus: Ad.addrNd_minus,
  249. addrN_minus: Ad.addrN_minus
  250. }, undefined, Buffer.concat([
  251. new Buffer.alloc(29),
  252. xor(Ad.addrNd_minus, String(Ad._id)),
  253. new Buffer.alloc(57),
  254. xor(Ad.addrN_minus, Ad.addrN),
  255. new Buffer.alloc(120)
  256. ]))
  257. }
  258.  
  259. //обновить next в As по адресу N_1 на N+1
  260. if (Ad.addrN_minus !== _null){
  261. await findAndUpdateAsIndex({
  262. _id: Ad.addrN_minus,
  263. next: Ad.addrN_plus
  264. }, undefined, Buffer.concat([ new Buffer.alloc(56), xor(Ad.addrN_plus, Ad.addrN), new Buffer.alloc(2) ]));
  265. }
  266.  
  267. //если это первый элемент, то есть N_minus равен нулю, а N_plus не нуль, то исправить указатель в Ts на N_plus
  268. if (Ad.addrN_minus === _null && Ad.addrN_plus){
  269. const tmp = `s.${Ad.word}`;
  270.  
  271. const [ Ts ] = await _indexTModel.aggregate([
  272. { $match: { _id: _word_index_id[key], [tmp]: { $exists: true } } },
  273. { $project: { [tmp]: 1 } }
  274. ]);
  275.  
  276. await _indexTModel.find ({ _id: _word_index_id[key] }).updateOne({
  277. $set: {
  278. [tmp]: String(xor(xor(Ad.addrN_plus, Ad.addrN), String(Ts.s[Ad.word])))
  279. }
  280. });
  281. }
  282.  
  283. if (Ad.addrN_minus === _null && Ad.addrN_plus === _null){
  284. const tmp = `s.${Ad.word}`;
  285. await _indexTModel.find({ _id: _word_index_id[key] }).updateOne({
  286. $unset: { [tmp]: 1 }
  287. });
  288. }
  289.  
  290.  
  291. let promises = []
  292.  
  293. //удалить запись в As по адресу N
  294. promises.push(_indexAModel.deleteOne({ _id: Ad.addrN }));
  295. await Promise.all(promises);
  296.  
  297. //переходим к следующему слову в удаляемом файле
  298. Ad_addr = Ad.addrD_plus;
  299. }
  300. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement